I get a problem with follwoing code.
my html page code :
<body ng-app="myapp">
<div ng-controller="myController">
The message is {{message}}
<input type="button" value="Change Message" ng-click="changeMessage()">
</div>
My Controller code:
app.controller('myController',function($scope)
{
$scope.changeMessage=function()
{
setTimeout(function(){
console.log("Message changed");
$scope.message="Hurray !!! New Message";
},3000);
$scope.newMessage=function()
{
$scope.message="hello";
console.log("new message");
};
But if I use changeMessage function I am not able to see the changed Message property even though the console.log message comes. what is missing here in both cases.
Thanks in advance
you should use $digest() after that the timeout is done:
$scope.changeMessage=function()
{
setTimeout(function(){
$scope.message="Hurray !!! New Message";
$scope.$digest();
},3000);
}
please note that it is much better to use $digest instead of $apply (performance related):
scope.$digest() will fire watchers on the current scope, and on all of its children, too. scope.$apply will evaluate passed function and run $rootScope.$digest()
every change should happen within an angular-digest-cycle. if you change values from the outside (which is exactly what happens, if you use setTimeout
instead of angular's $timeout
) angular does not update your view until the next digest-cycle ( https://www.ng-book.com/p/The-Digest-Loop-and-apply/ ). so in your case the message
is already set, but the view has not been updated.
try something like this:
app.controller('myController', function($scope, $timeout) {
$scope.changeMessage = function() {
$timeout(function(){
console.log("Message changed");
$scope.message="Hurray !!! New Message";
}, 3000);
$scope.newMessage=function() {
$scope.message="hello";
console.log("new message");
};
The reason that the change isn't reflected in the view is that because of the assignment is done in the callback in setTimeout
which results in angular not noticing the change. This has to do with the so called digest
cycle. There are different ways to solve this.
use $scope.$apply()
to wrap your assignment
or even better use the existing $timeout
service provided by angular instead of the call to setTimeout
which already handles the problem above for you.
For details, see https://docs.angularjs.org/api/ng/service/$timeout for usage of $timeout
and https://docs.angularjs.org/api/ng/type/$rootScope.Scope for the reasons behind $apply.
A general explanation of what is happening here is described at http://www.sitepoint.com/understanding-angulars-apply-digest/
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.