Javascript 如何正确使用AngularJS摘要循环

Javascript 如何正确使用AngularJS摘要循环,javascript,angularjs,angularjs-digest,Javascript,Angularjs,Angularjs Digest,我一直在研究AngularJS摘要周期的注意事项,我想更好地理解正确使用和不正确使用之间的区别 例如,如果我的AngularJS代码如下所示: var myApp = angular.module("testApp", []); myApp.controller("testController", ["$scope", "$timeout", function($scope, $timeout){ setTimeout(function(){ $scope.userna

我一直在研究AngularJS摘要周期的注意事项,我想更好地理解正确使用和不正确使用之间的区别

例如,如果我的AngularJS代码如下所示:

var myApp = angular.module("testApp", []);

myApp.controller("testController", ["$scope", "$timeout", function($scope, $timeout){
    setTimeout(function(){
        $scope.username = "Test User name";
    }, 3000);

    $timeout(function(){
        $scope.username = "AngularJS User name";
    }, 3000);
}]);
为什么
setTimeout
没有被用作摘要周期的一部分,而
$timeout
却被用作摘要周期的一部分,我该如何解决这个问题


请记住,我不仅在寻找代码解决方案,而且在寻找对发生这种情况的原因的解释。虽然代码解决方案可能会很好,但它不会解释自身

$timeout
setTimeout()
的一个角度化版本,即它的编码方式会触发摘要循环
setTimeout()
是一个普通的Javascript函数,它对角度循环或摘要循环一无所知。由于
setTimeout()
不是一个简单的JS对象,Angular无法
$watch
监视它

因此,像
$timeout
这样的功能的全部意义在于,它们是一些Javascript功能的角度友好版本。

$timeout()
setTimeout()
不一样,$timeout是角度化的

它在内部使用promise($q服务),它将在每个摘要周期后自动解析。而
setTimeout()
,只是在队列中注册回调函数的一个技巧

如果希望setTimeout()成为摘要循环的一部分,请在$scope内调用它。$apply()


更一般的解释是,
setTimeout
在angular内部不起作用,因为它将其回调放在事件循环上,angular不监视该循环。如果直接创建
XMLHttpRequest
而不是
$http
,也会发生同样的情况


Angular对这些实用程序/对象进行了自己的抽象,因此当它们完成时,摘要周期将获取任何更改。

setTimeout不是Angular的一部分,因此不会触发更改检测。解决这个问题的方法是$timeout,还有什么需要解释的呢?@LukaJacobowitz我不明白为什么会这样,当AngularJS通常将代码包装在
$scope.$watch
函数中,然而,尽管它不在
setTimeout
中查看,但是
setTimeout
只是一个普通的javascript函数,所以不能$watch它。@LukaJacobowitz所有其他普通javascript函数也是这样吗?也就是说,如果我想在摘要循环中使用一个,我必须确保AngularJS知道它们?是的,事实上,来自jQuery的人常常会想,为什么调用jQuery函数时检测不到更改。有趣的是,因此,任何其他javascript本机函数以及未进行角度化的函数也将受到此类限制?这意味着我应该寻找它的服务版本,并期望它以角度的方式工作?通常情况下,其他JS函数没有触发摘要周期的效果。DOM操作函数会有所不同,这就是为什么不应该使用JS或本机DOM操作,而应该将其留给Angular及其模板(当然,它知道摘要循环)或使用angularized
Angular.element
方法。AngularJS中内置的
$watch
功能保护
$scope
objectOk的属性,因此AngularJS中通常使用普通JavaScript函数来处理数组操作之类的更改模型并因此触发摘要的事情,只有在符合AngularJS在其上所做的操作的情况下,才可以安全地用于范围或DOM操作。我现在明白了。这是一般的想法,是的。感谢你的解释,我修改了你的答案,正确地使用了
$scope.$apply
,这是一般解释的更好版本,特别是考虑到AngularJS摘要循环与JavaScript本机事件循环,巨大的差异对裸体来说是看不见的eye@AGE好到我能拿到绿色支票吗?:)
setTimeout(function(){
    $scope.$apply(function(){
        $scope.username = "Test User name";
    });
}, 3000));