我知道我问的是一个回答非常简单的问题(我是棱角分明的新人,在这里问这个问题确实需要很大的勇气;)。我有一个指令显示这样的时间:
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周期,但事实并非如此。我知道使用setInterval
ot $timeout
是另一种方法,但我真的不想要一个时钟,我想知道为什么更新不会发生。顺便说一句,我在检查$apply()
之后打电话给$$phase
- 没有帮助
谢谢。
答案 0 :(得分:5)
$ watch函数默认按引用比较对象,对于字符串/数字值更快更好,但不适用于像Date这样的复杂对象 - 日期可能会改变,但它总是相同的Date对象,所以引用不会改变。
这是为了避免在巨大阵列上进行严重的等式测试。
现在,虽然这可能有用(注意$ watch函数的第三个参数设置为true):
scope.dTime = new Date();
scope.$watch( function(scp){ return new Date(); }, function(newVal){
scope.dTime = newVal;
}, true
);
每次轮询$ watch函数(意味着每个应用程序周期)时,它可能会触发更改事件。
如果你想要if每秒触发,请从Date()返回秒数,返回类似于返回Math.floor(new Date()。valueOf()/ 1000)。然后根据需要设置dTime。
<强>更新强>
虽然angular的检查适用于return Date()
,但问题是由于angular的脏检查系统 - 它只会在模型上触发更改时检查$ watch函数(意味着在$ scope中定义的模型) )。
这个来自Valentyn Shybanov的Plnkr可以作为一个例子 - 时钟函数触发模型上的变化,并且该变化触发$ watch函数。
ALSO ,请注意使用window.setTimeout的this version。它只能使用$ apply方法通知angularJS发生了更改。
答案 1 :(得分:2)
“我想了解为什么更新不会发生。”
我认为这张照片(来自Conceptual Overview page)最能说明:
除非调用$ apply(),否则不会检查$ watch列表。 $ apply是我们进入“$ digest循环”的方式。许多(所有?)Angular内置指令自动调用$ apply(所以我们没有)。例如,正如@Tiago已经提到的,更改绑定的$ scope属性(在Angular内)将导致$ apply被调用。我们也可以自己明确地调用$ apply(例如,从我们定义的第三方库回调函数内部 - 如果我们不在这里调用$ apply,我们将不会进入$ digest循环)。
底线:除非我们进入蓝框(“Angular执行上下文”),否则不会检查$ watch列表 - 因此不会执行脏检查。