I have a specific problem which I can't seem to crack.
In html I have following code:
<select ng-model="$parent.proizvod" ng-options="i.id_proizvod as i.proizvod for i in proizvodiServer">
<option>Select</option>
</select>
And in my controllers:
$rootScope.proizvod = '1';
So when the page first loads, the first option is selected. If I change the $rootScope.proizvod = '1';
to $rootScope.proizvod = '3';
It will load the third option.
Now, when you select some other value, it will store it in $rootScope.proizvod
, but later, in some function, I want to reset that $rootScope.proizvod
back to '1' and it doesn't seem to be working.
What am I missing here?
P.S. without $parent.proizvod
, my select doesn't even change the $rootScope.proizvod
value.
EDIT: Here's the other fucntion:
$rootScope.upisPodataka = function() {
setTimeout(function () {
$rootScope.proizvod = '1';
$scope.$apply();
}, 2000);
$state.go('app.podesenost_grilla', {}, {
reload: true
});
upisPodataka function is called on a click of a button.
Using ng-model='$parent.proizvod'
is not guaranteed to update $rootScope
in all circumstances.
New AngularJS developers often do not realize that
ng-repeat
,ng-switch
,ng-view
,ng-include
andng-if
all create new child scopes, so the problem often shows up when these directives are involved.
If the ng-model
sets the value in a child scope. The child scope gets its own property that hides/shadows the parent property of the same name. This is not something AngularJS is doing – this is how JavaScript prototypal inheritance works. Read the Wiki.
So the question becomes should it be $parent.$parent.proizvod
? Or maybe $parent.$parent.$parent.proizvod
? Do it by trial and error?
A more robust approach is to use the ng-change directive to update the variable.
<select ng-model="vm.proizvod" ng-change="vm.update()"
ng-options="i.id_proizvod as i.proizvod for i in proizvodiServer">
<option>Select</option>
</select>
vm.update = function () {
$rootScope.proizvod = vm.proizvod;
console.log($rootScope.proizvod);
});
Instead of using $rootScope
, consider using a custom service to store the variables.
$rootScope
exists, but it can be used for evilScopes in AngularJS form a hierarchy, prototypically inheriting from a root scope at the top of the tree. Usually this can be ignored, since most views have a controller, and therefore a scope, of their own.
Occasionally there are pieces of data that you want to make global to the whole app. For these, you can inject
$rootScope
and set values on it like any other scope. Since the scopes inherit from the root scope, these values will be available to the expressions attached to directives likeng-show
just like values on your local $scope.Of course, global state sucks and you should use
$rootScope
sparingly, like you would (hopefully) use with global variables in any language. In particular, don't use it for code, only data. If you're tempted to put a function on$rootScope
, it's almost always better to put it in a service that can be injected where it's needed, and more easily tested.Conversely, don't create a service whose only purpose in life is to store and return bits of data.
$rootScope.upisPodataka = function() {
//setTimeout(function () {
$timeout(function () {
$rootScope.proizvod = '1';
//$scope.$apply();
}, 2000);
$state.go('app.podesenost_grilla', {}, {
reload: true
});
};
The $timeout service wraps windows.setTimeout
and integrates it with the AngularJS framework and its digest cycle. Then $apply()
is not needed.
In addition, $timeout.flush()
can be used when testing.