Reputation: 161
I want share data between controller, so though service, I can easily get and set data. But if a data set by a function in function in service, it's can not update controller's data. like this:
_this.testf = function (){
_this.test.push(1);
_this.test.push(1);
_this.test.push(1);
$timeout(function (){
_this.test.push(2);//this can not seen in controller
}, 1000);
}
The new data still can be update by $watch, but it's not same as reference.
Here is the example code:http://codepen.io/nsbp/pen/MwdqRq
Upvotes: 3
Views: 121
Reputation: 18513
The problem is that ng-bind
will only update when the object you pass into it is replaced with another object. Since you are passing it an array and you are only updating the element of the array ng-bind
will not update. You could fix this by either using an ng-repeat
or by using {{}} in place of ng-bind.
<p>
<span ng-repeat="item in test track by $index" ng-bind="item"></span>
</p>
http://codepen.io/anon/pen/QbRZxz
Upvotes: 1
Reputation: 33833
The issue occurs because your controller's digest cycle has already ended by the time the timeout period elapses. If you add a quick and dirty check like the following to your pen:
_this.testf = function (){
_this.test.push(1);
_this.test.push(1);
_this.test.push(1);
$timeout(function (){
_this.test.push(2);
alert(_this.test.length);
}, 1000);
}
You will see that the array IS updated.
As a result, you can either use $watch
or $timeout
in your controller, or broadcast an event from your directive to your controller to trigger a new digest cycle.
If using $timeout, your assigned binding won't recognize that the data has updated (whereas $watch will if using a deep watch, watching the array length, or if you're using $watchCollection), but you can force it to update by copying the array, which is actually creating an entirely new reference.
.controller('MainCtrl', function($scope, $timeout, List) {
$scope.test = List.test = [];
List.testf();
$timeout(function (){
$scope.test = angular.copy(List.test);
}, 4000);
});
Upvotes: 1
Reputation: 7740
This is because the $timeout
service is asynchronous.
You could have your service return
the value and then in your controller set it in the returned promise, like:
.service('List', function($timeout) {
var _this = this;
_this.test = [];
_this.testf = function (){
_this.test.push(1);
_this.test.push(1);
_this.test.push(1);
return $timeout(function (){
_this.test.push(2);
return _this.test;
}, 1000);
}
})
.controller('MainCtrl', function($scope, $timeout, List) {
List.testf().then(function(test) {
$scope.test = test;
});
});
Here is an updated codepen.
Upvotes: 1