【问题标题】:How does Angular update the view after a $digest cycle?Angular 如何在 $digest 循环后更新视图?
【发布时间】:2016-02-27 18:54:48
【问题描述】:

是吗:

1) 运行 DOM(从 ng-app 开始),如果它看到带有指令的 DOM 节点,则使用相应的模型值更新该 DOM 节点。

2) 在运行$$watchers 列表时,如果它检测到更改,它会引用它需要更新的 DOM 节点,所以它只是这样做(而不是运行整个 DOM,使用这个方法,它会存储并使用对$$watchers中节点的引用)。

【问题讨论】:

    标签: javascript angularjs model-view-controller


    【解决方案1】:

    更多的是第二种方法。

    Angular 通过指令完成所有繁重的工作。你在 Angular 中使用的几乎所有东西都是指令:

    <div ng-app>
    <div ng-controller>
    <button ng-click>
    
    <!-- input is actually a directive -->
    <input ng-model="foo" />
    

    所有这些小指令都获得了对它们所附加的 DOM 元素的引用,以及一个 $scope 对象。 指令只是注册一个回调,以便在发生变化时执行。

    正如您已经指出的,这些称为观察者。

    范围是分层的,所以总是有一个相关对象树构成您的应用程序状态。当$digest 循环开始时,它会递归地遍历该树以查找更改,并触发回调(又名观察者)

    回调可以选择做它想做的任何事情。只是在大多数情况下,它正在更新 DOM。

    归根结底,它的发生方式并没有什么神奇之处。只是一个回调结构,当发生变化时会被执行。

    这是一个自定义指令的愚蠢示例,它注册一个观察者并在某些属性更改时更新 DOM。

    (function(){
    
      function getRandomInt(min, max) {
      return Math.floor(Math.random() * (max - min)) + min;
    }
      
      function updateValue(){
        return {
          restrict:'A',
          link: function(scope, elem, attrs){
            elem.on('click', function(){
              //You would never actually do this, but
              // it's a demo
              scope[attrs.updateValue] = "rgb(" + 
                getRandomInt(0, 255) + "," +
                getRandomInt(0, 255) + "," +
                getRandomInt(0, 255) + ")";
              
              //kick off a digest loop manually
              // this is similar to what a lot of angular
              // directives do.
              scope.$digest();
            });
          }
        };
      }
      
      function sillyDomChangeOn(){
        return {
          restrict:'A',
          link: function(scope, elem, attrs){
            scope.$watch(attrs.sillyDomChangeOn, function(newVal, oldVal){
              elem.css('color', newVal);
            });
          }
        };
      }
      
      angular.module('my-app', [])
        .directive('updateValue', updateValue)
        .directive('sillyDomChangeOn', sillyDomChangeOn);
    
    }());
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css">
    
    <div ng-app="my-app" class="container">
      <button type="button" class="btn btn-primary" update-value="randomVal">Update Value</button>
      <h3>Value: <code>{{randomVal}}</code></h3>
      <div class="well" silly-dom-change-on="randomVal">
      <h3>This is just a random DIV</h3>
        <div>
    </div>

    【讨论】:

    • 谢谢!既然您解释了它是有道理的,但我最初忘记了摘要循环与指令的关系。我现在明白它(经常)在一个指令中调用,它可以访问 DOM 元素(这就是它访问 DOM 元素的方式!)。 ngBind's source的相关链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多