service implementation
myService = function()
{
this.config = {
show0: false,
show1: true,
role : -1,
id : -1;
};
};
in controller, I map the config values
$scope.config = myService.config; //I guess this by reference, isnt it???
in templates of these controllers for e.g. the $scope.config.show0 is used with for e.g. ng-model
Now outside angular in my threejs code
I get the service using injector which I have defined earlier and change some values depending on certain conditions
var service = window.my.injector.get('myService');
service.config.id = 1991;
Now this value is not immediately reflected in the HTMl template,
Source = {{config.id}} still renders as Source = -1
But when I click on some other button in the same template which is mapped to any other value in the same scope
Source = {{config.id}} still renders as 1991
How should I force this rerendering or refreshing in my non angular code soon after
var service = window.my.injector.get('myService');
service.config.id = 1991;
///do something to refresh that controller
Am I using the service wrong? How should I make this config available in angular controllers, templates and non angular code if not via a service?
Shouldnt changing the $scope.config properties values and changing the values outside angular by retrieving the service via injector change the values everywhere ?
This is because the angular digest cycle does not kick in from your threejs code. I am not sure where your three js code is, but try using $scope.$apply to kick in the digest cycle, and it should work fine.
If you can share a jsFiddle, I can have a better understanding on what you are trying to achieve, but the reason why this is not happening is, as I said, that the digest cycle does not kick in.
Related
Now, I know this is an off-the-wall question and that there is probably not going to be any API level access for doing this. I also understand that doing this is completely unnecessary. However, the implementation that I am aiming for requires for me to be able to make {{ variable }} look inside of the $scope.object instead of the $scope itself.
For example:
Controller($scope) {
$scope.active = ...;
}
In this case you can get the active object through {{active}} and any child elements through {{active.broken}} however for the sake of humoring me, lets assume that all of the variables I'm ever going to have to obtain is going to be part of that active object. So I'll be typing things like.. (Data not related)
{{active.title}}
{{active.author}}
{{active.content}}
You could just say "Well why not just move the title/author/content into the $scope and keep it outside of the active object, as that would achieve the desired result of this:
{{title}}
{{author}}
{{content}}
Well, that's where the problem comes in. This is a controller that is not exposed to my end-user, however the end-user does have a completely mutable object (in this example: active) that they can modify. This object has many [optional] listeners and callbacks that are invoked by the application controller when necessary.
The user's that have used my application during testing have commented on what a drag it is to have to type in active. before everything in order to get the data they wanted. Considering data from the $scope is never rendered to the screen, and only data from active is, I was wondering if perhaps there was a way to change where AngularJS looks when parsing/binding data.
If the goal is to evaluate expressions in a different context than $scope, that can be done with the $parse service.
app.controller("myVm", function($scope, $parse) {
var vm = $scope;
vm.active = { a: 5,
b: 3
};
var.myFn = $parse("a+b");
vm.total = myFn(vm.active);
console.log(vm.total);
});
The above example shows how to evaluate the expression a+b using the properties of the $scope.active object.
The DEMO on JSFiddle
I have a user.list.ctrl and a user.detail.cntr. All the controllers are build as a module and are injected in a "user-module" which I inject in the app.js. (see the complete code in the plunker below)
my controller module
angular.module('user-module', ['user-module.controllers']);
my user-module
angular.module('demo.app', ['user-module']);
In both controllers i inject user-Fctr with data from a REST factory. (works well)
user.list.cntrl has a $scope.refresh()
user.detail.cntrl has a $scope.update()
user.list.cntrl
When I enter a new record, i call the $scope.refresh() so I can refresh the list. (this is working fine)
user.detail.cntrl
When i click a user from the list, the user detail loads in a different view (works ok)
when I update the user.detail, I want to call $scope.refresh() to update the user.list , but it is not working. I cannot call $scope.refresh()
I thought that since I inject the same factory into both controllers I can use each others $scopes.
Any ideas on how I can use $scope.refresh() (or update the list when I update the user.detail.js)
I make a plunker with all the js files (the plunker is not functional, it is only to show the code that I have)
http://plnkr.co/edit/HtnZiMag0VYCo27F5xqb?p=preview
thanx for taking a look at this
This is a very conceptual problem.
You have created a controller for each "piece" of view because they are meant for different activities. This is the purpose of controllers. So that is right.
However, you are trying to access the refresh function, written in one controller, in another one. Taken literally, this is wrong, since then, refresh is out of place either inside the user list controller or the detail controller.
A function that is meant to control (literally) what is happening on a specific piece of view is a controller. - There you are right having a controller for the list and one for the details.
A function that is meant to be shared between controllers must be a service. This is exactly what you want for your refresh function to be.
Whenever you inject the same factory into n controllers, you can't use the scope of every controller. This isn't the purpose of a controller.
However, whenever you inject the same factory into n controllers, you can use its exposed methods.
The problem you have, can be solved as follows:
app.factory( 'sharedFunctions', [ 'factoryId', function sharedFunctions( factoryId ) {
var refresh = function () {
factoryId.getAll(/*your params to query*/)
.success( function ( response ) {
//This will return the list of all your records
return response;
});
};
return sharedFunctions;
}]);
With this factory service registered, then you can inject it to your controllers and whenever you need to refresh, just call the exposed method of the service and plot the new information into the view.
Hope it works for you!
i ended up doing this:
I added in the list.contrl this:
factoryId.listScope = $scope;
since I already have the factoryId (my data service) injected in the detail controller, I can call this:
factoryId.listScope.refresh();
it works but I don't know if this is the best way. any comments?
I have two states using the same controller, when I trigger a function from State 1, I want it to go to state 2 and changes its title as well, here's my code:
$scope.page2Title = "Testing";
$scope.aFunction = function(){
$scope.page2Title = "Hello";
$state.go('eventmenu.page2');
};
But page2's title is not updated to "Hello", it is still "Testing". I also tried $scope.apply() but doesn't work either.
Your $scope.page2Title is a local scope to the controller. It would not be available when the new view is loaded.
Using $rootScope or a service would allow the data to be persistent between views. I think for what you are doing $rootScope would be appropriate.
If you were looking to store business logic or data I would recommend using a service.
About $rootScope
New to Angular and I am trying to figure out Value. I am trying to save a value that I can later inject into my controller but for some reason, it breaks. If you run the plnkr sample, it will work, code gets to the controller. If you comment out line 68 and un-comment 67, it breaks the application. Line 41, I just set a value which is what I want to pass into my controller.
Why would this not work?
http://plnkr.co/edit/SnOm2r?p=options
There is no AppConfig...if you want to inject AppConfig it has to exist somewhere, a directive, a service, a factory, SOMETHING. You don't currently have one being loaded.
Your issue is a timing issue. The controller is created before the value is set so it doesn't have access.
If you create like this:
var mainApp = angular.module("Test", ["ui.router"]);
mainApp.value("AppConfig", 1.0);
Then you can access it right away. If you have to set it asynchronously (i.e. you plan to set it as the result of a call) then the best way is probably to inject the $injector instead of the AppConfig. Then you can do:
if ($injector.has("AppConfig")) { value = $injector.get("AppConfig"); }
Even better may be to move that into a service with a promise that can return the value once it's fetched then cache it for subsequent calls.
Final Solution? It looks like I had my routing and controllers a little confused. I had my routing in a file with my controller module. I moved my routeProvider into the main module, like in the tutorial example. My controller and my routeProvider where under the same module. Maybe that was confusing everything. So now I have the controller in it's own module, and the routeProvider is under the main module. That seems to have fixed the problem without needing to initialize the search field to force the bindings to update the data.
Update:
The solution to showing my data at the time the page loads was to use an older version of angularJs, or use ng-Init and initialize the search field to a blank space.
I'm getting JSON data from the firebase website to update a table. I have a search field that works. The data will not display in the table until I type something into the search field. I don't know why the data won't just display in the table as soon as the controller is done getting the data.
Note: The link to the backend data is now removed, I don't want to keep that database file there indefinitely.
Here is the link to the jsFiddle code:
Last Version jsFiddle
Here is code for the controller.
'use strict';
/* App Module */
// Create the module named 'testApp'
var testApp = angular.module('theTestApp', [
'ngRoute',
'testServices'
]);
'use strict';
/* Services */
var testServices = angular.module('testServices', []);
testServices.controller('CommonController',
// function($scope, $http, $route) {
function($scope, $http) {
//access the customInput property using $route.current
//var dbKey = $route.current.customInput;
var dbKey = 'test-a-db-12345';
var urlToDb = 'https://' + dbKey + '.firebaseio.com/rows/.json';
$http.get(urlToDb).success(function(data) {
$scope.UsedItems = data;
});
});
How do I get the data to display as soon as it's loaded?
Update 1: I'm assuming that the data is already there, but the event of typing something into the search field triggers the filter, and then the data shows up. It shows up filtered.
Update 2: I'm reading about $Watch There is constantly and event loop listening for events. When a key is pressed in the search box, the bindings {{name}} get updated if something has changed. In this case, the content of the search input field was changed. So the issue seems to have something to do with when the bindings get updated, not whether the data is getting retrieved.
Update 3:
This version of the code runs. It loads the data when the page is rendered. Here is a working example in jsBins.
Update 4:
As of angularJs version 1.2.0 the behavior changes. Versions 1.0.8, 1.0.7 will instantly display my data when the page loads, 1.2.0 will NOT! I just happened to be using jsBins which uses 1.0.7, and it started working. Didn't know why until I started comparing the differences. Hopefully, there is a way to make it work in newer versions.
jsBins Working Example
The problem is that theSearch.Txt is empty. And you are filtering by that. My guess is that Angular at that moment decides to not let anything through and thus doesn't display anything.
What you should do:
Initialize the variable with a space filled string. (i.e. ' ')
Here is a working jsFiddle.
I used ngInit here. But that is because you decided to link?? the controller instead of putting it into a script tag. I suggest that next time you rather take the additional effort into pasting it in, as using the ngInit directive makes me feel like using eval.
Try
$scope.$apply(function(){
$scope.UsedItems=data;
}