Angular如何在$摘要周期后更新视图?

时间:2015-11-25 05:04:28

标签: javascript angularjs model-view-controller

是吗:

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

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

1 个答案:

答案 0 :(得分:3)

这是第二种方法。

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>