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
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.
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);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With