2

我知道我在问一个答案非常简单的问题(我是 Angular 新手,在这里提出这个问题确实需要很大的勇气;)。我有一个指令显示这样的时间:

Application.Directives
.directive('theClock', function(){
    return {
        retrict: 'EA',
        templateUrl: 'partials/partial.clock.html',
        link: function(scope, elem, attrs) {

            scope.dTime = Date();
            scope.$watch( function(scp){ return Date(); }, function(newVal){ 

                    scope.dTime = newVal;
                }
            );
        }
    };
});

我希望时间会更新每个 $digest 周期,但事实并非如此。我知道使用setIntervalot$timeout是另一种方法,但我真的不想要时钟,我想了解为什么更新不会发生。顺便说一句,我$apply()在检查后确实打电话$$phase- 没有帮助

谢谢你。

4

2 回答 2

5

$watch 函数默认按引用比较对象,这对于字符串/数字值更快更好,但不适用于像 Date 这样的复杂对象 - Date 可能会更改,但它始终是相同的 Date 对象,所以引用没有改变。

这是为了避免对巨大数组进行大量的相等测试。

现在,虽然这可能有效(注意 $watch 函数的第三个参数设置为 true):

scope.dTime = new Date();
scope.$watch( function(scp){ return new Date(); }, function(newVal){ 

  scope.dTime = newVal;
  }, true
);

它可能会在每次轮询 $watch 函数时触发更改事件(意味着每个应用程序周期)

如果您想每秒触发一次,请从 Date() 返回秒数,例如 return Math.floor(new Date().valueOf()/1000)。然后根据需要设置 dTime。

更新

虽然 Angular 的检查可以使用return Date(),但问题是由于 Angular 的脏检查系统 - 它只会在模型(意味着在 $scope 中定义的模型)触发更改时检查 $watch 函数。

这个从 Valentyn Shybanov分叉出来的 Plnkr 可以作为一个例子 - 时钟函数触发模型的更改,并且该更改触发 $watch 函数。

另外,请注意这个版本,它使用了 window.setTimeout。它只能使用 $apply 方法来通知 angularJS 发生了变化。

于 2013-01-09T13:15:45.493 回答
2

“我想了解为什么没有更新。”

我认为这张图片(来自概念概述页面)最好地解释了它:

角事件循环

除非调用 $apply(),否则不会检查 $watch 列表。$apply 是我们进入“$digest 循环”的方式。许多(全部?)Angular 内置指令会自动调用 $apply(所以我们不必这样做)。例如,正如@Tiago 已经提到的,更改绑定的 $scope 属性(在 Angular 内部)将导致 $apply 被调用。我们也可以自己显式调用$apply(例如,从我们定义的第三方库回调函数内部——如果我们不在这里调用$apply,我们就不会进入$digest 循环)。

底线:除非我们进入蓝色框(“Angular 执行上下文”),否则不会检查 $watch 列表——因此不会执行脏检查。

于 2013-01-09T17:49:34.433 回答