简体   繁体   English

Angular JS中的双向绑定

[英]Two way binding in Angular JS

I get a problem with follwoing code. 我对以下代码有疑问。

my html page code : 我的html页面代码:

<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. 但是,如果我使用changeMes​​sage函数,即使console.log消息来了,我也看不到更改后的Message属性。 what is missing here in both cases. 两种情况下这里都缺少什么。

Thanks in advance 提前致谢

you should use $digest() after that the timeout is done: 您应该在超时后使用$ digest():

$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): 请注意,最好使用$ digest代替$ apply(与性能相关):

scope.$digest() will fire watchers on the current scope, and on all of its children, too. scope。$ digest()将在当前范围及其所有子级上引发监视程序。 scope.$apply will evaluate passed function and run $rootScope.$digest() scope。$ apply将评估传递的函数并运行$ 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/ ). 如果您从外部更改值(如果使用setTimeout而不是angular的$timeout ,这确实会发生这种情况)angular直到下一个摘要循环( 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. 因此,根据您的情况,该message已经设置,但视图尚未更新。

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. 更改未反映在视图中的原因是,由于分配是在setTimeout的回调中完成的,因此导致角度没有注意到更改。 This has to do with the so called digest cycle. 这与所谓的digest周期有关。 There are different ways to solve this. 有多种解决方法。

use $scope.$apply() to wrap your assignment 使用$scope.$apply()包装您的作业

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. 甚至更好地使用angular提供的现有$timeout服务,而不是调用setTimeout (已经为您解决了上述问题)。

For details, see https://docs.angularjs.org/api/ng/service/$timeout for usage of $timeout 有关详细信息,请参阅https://docs.angularjs.org/api/ng/service/$timeout了解$ timeout的用法

and https://docs.angularjs.org/api/ng/type/$rootScope.Scope for the reasons behind $apply. https://docs.angularjs.org/api/ng/type/$rootScope.Scope ,原因是$ apply背后的原因。

A general explanation of what is happening here is described at http://www.sitepoint.com/understanding-angulars-apply-digest/ http://www.sitepoint.com/understanding-angulars-apply-digest/中介绍了此处发生的情况的一般说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM