Javascript 为什么这两个更新没有反映在视图中?

Javascript 为什么这两个更新没有反映在视图中?,javascript,angularjs,angularjs-scope,Javascript,Angularjs,Angularjs Scope,我试图了解如何通过控制器正确操作属性。以下代码在四秒钟内执行六次更新。更新2和更新3不会反映在视图中。为什么会这样?我需要做什么才能让这些类型的更新影响视图 Html <div ng-controller="Controller"> myValue: <span ng-bind="myValue"></span> </div> 使用$timeout而不是setTimeout选择进入摘要周期秒不会显示,因为摘要循环的轮次覆盖了myValu

我试图了解如何通过控制器正确操作属性。以下代码在四秒钟内执行六次更新。更新2和更新3不会反映在视图中。为什么会这样?我需要做什么才能让这些类型的更新影响视图

Html

<div ng-controller="Controller"> 
    myValue: <span ng-bind="myValue"></span>
</div>

使用
$timeout
而不是
setTimeout
选择进入摘要周期<代码>秒不会显示,因为摘要循环的轮次覆盖了
myValue
的值


更新的fiddle:

使用
$timeout
而不是
setTimeout
选择进入摘要周期<代码>秒不会显示,因为摘要循环的轮次覆盖了
myValue
的值


更新的提琴:

你可以尝试
{myValue}}
而不是
{code>元素

你可以尝试
{myValue}}
而不是
元素

,所以我在原始问题中显然不够清楚,正如投票结果(正确)建议使用
$timeout
而不是
setTimeout
,然而,最初的目的是理解为什么更新没有反映在视图中,以及如何使这些类型的更新(起源于角度之外)影响视图

阅读范围指南 因此,虽然我选择跳过《开发人员指南》的第二部分,因为它看起来是最无聊的,但它可能是最重要的,并且它清楚地指出了理解角度绑定数据的一些必要事项,特别是注意到的范围生命周期

当浏览器调用JavaScript时,代码在外部执行 Angular执行上下文,这意味着Angular不知道 模型修改。要正确处理模型修改 执行必须使用
$apply
方法。仅在
$内执行的模型修改适用
方法将通过角度适当说明

有一个很好的例子可以进一步解释这个概念。第一种情况恰当地重申了理解范围的重要性:

你需要了解角度是如何工作的才能理解 它

不要只调用$scope.$apply 因此,您开始在各地添加对
$scope.$apply
的调用,以满足这些源于angular之外的需求,但最终您开始得到:

Error: $digest already in progress
这意味着您不能在执行
$digest
时调用
$scope.$apply
。在此之后,您可能会想,如何根据
$digest
当前是否正在运行,有条件地调用
$scope.$apply
。但是,你不需要这样做

只需使用$timeout 哈,就像,我知道,但基于一个不同的思维过程,我认为。看
$timeout
不仅仅是用来代替
设置超时
,而是用来(没有
延迟
)包装从作用域生命周期之外调用的任何模型更新,这样做可以确保与任何当前处理的
$digest
没有冲突

收尾 因此,在原始代码段中,第二次和第三次更新不会反映在视图中,因为它们是在角度执行上下文之外执行的。第三次更新不会影响模型这一事实也意味着在执行上下文之外调用事件也不会使您进入执行上下文

第四个更新已经包装在
$interval
中,这本身会导致在下一个摘要中运行该代码的更新。因此,更新代码以显示角度执行上下文之外的事件示例,该事件导致其更新显示在视图中,如下所示:

setTimeout(function() { 
    $timeout(function({ // start wrap
        $scope.myValue = "second";  // now this updates!
        console.log($scope.myValue);
        $scope.$emit("my-event", "third"); // now this updates!
    })); // end wrap
    console.log($scope.myValue);
    $interval(function() {
        $scope.$emit('my-event', "fourth");
    }, 1000, 1);
}, 1000);

因此,我在最初的问题中显然不够清楚,因为投票结果(正确)表明使用
$timeout
而不是
setTimeout
,然而,最初的目的是理解为什么视图中没有反映更新,以及可以做些什么来获得这些类型的更新(从角度外开始)按预期影响视图

阅读范围指南 因此,虽然我选择跳过《开发人员指南》的第二部分,因为它看起来是最无聊的,但它可能是最重要的,并且它清楚地指出了理解角度绑定数据的一些必要事项,特别是注意到的范围生命周期

当浏览器调用JavaScript时,代码在外部执行 Angular执行上下文,这意味着Angular不知道 模型修改。要正确处理模型修改 执行必须使用
$apply
方法。仅在
$apply
方法将通过角度适当说明

有一个极好的例子进一步解释了这个概念。第一个例子恰当地重申了理解范围的重要性:

你需要了解角度是如何工作的才能理解 它

不要只调用$scope.$apply 因此,您开始在各地添加对
$scope.$apply
的调用,以满足这些源于angular之外的需求,但最终您开始得到:

Error: $digest already in progress
这意味着您不能在执行
$scope.$apply
时调用
$digest
。之后,您可能会想,我如何根据
$digest
当前是否正在运行来有条件地调用
$scope.$apply
。但是,您不需要这样做

只需使用$timeout 哈,就像,我知道,但基于不同的思维过程,我认为。参见。
$timeout
不仅仅是用来代替
setTimeout
,而是用来(没有延迟)包装任何模型更新