使用SetInterval / SetTimeout更新范围

时间:2015-09-17 16:20:46

标签: angularjs angularjs-directive

我试图创造一个"时钟"指令作为学习Angular的一种方式。我如何确定它"滴答?"

这是我尝试的fiddle Link

angular.module('app')
.directive('clock' , function(){
  return {
    restrict: 'E',
    template: '<div>{{date}}</div>',
    link: function(scope, elem, attr){
      scope.date = getDate();
      setInterval(function(){
        scope.date = getDate();
      }, 100);
    }
  }
})

使用setInterval来更新范围变量是不行的。我假设是因为该指令不再观察它是否会发生变化?

1 个答案:

答案 0 :(得分:10)

它正在更新范围变量,但Angular不知道更改。

建议使用Angular $interval

以下是$intervalhttps://jsfiddle.net/oafcde6g/11/

的小提琴

换句话说,Angular没有通过“监听”范围属性来做任何魔术,它只是进行脏检查。但要做到这一点,需要通知一些事情发生了变化。因此,如果您真的想使用setInterval代替$interval,您可以手动通知它发生了变化:

setInterval(function () {
    scope.$apply(function () {
        scope.date = getDate();
    });
});

这样,您通知它在$apply内运行您的匿名函数,然后消化范围,检查是否有任何更改。如果是,它将更新视图。

ng- *事件的“魔力”(ng-click,ng-model等)

即使看起来像angular会自动知道在使用它的内置指令单击/更改某些内容时重新呈现视图,但事实并非如此。

ng-click的一些简单实现看起来像:

angular.module('app')
.directive('ngClick' , function(){
  return {
    restrict: 'A',
    link: function(scope, elem, attr){
        elem.on('click', function () {
            scope.$apply(function () {
                scope.$eval(attr.ngClick);
            });
        });
    }
  }
})

如果您尝试在角度上下文之外正常绑定click事件并使其更改范围变量,则可以自己查看。在您明确告知之前它不会更新(就像我们在setInterval示例中所做的那样)。