为什么 Scope.$apply() 调用 $rootScope.$digest() 而不是 this.$digest()? [英] Why Scope.$apply() calls $rootScope.$digest() rather than this.$digest()?

查看:32
本文介绍了为什么 Scope.$apply() 调用 $rootScope.$digest() 而不是 this.$digest()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 AngularJS 作用域中,$apply() 在每个事件处理程序(输入指令的 keydown/输入事件,选择指令的更改事件等)和其他一些情况下被调用.

In AngularJS scope.$apply() is called on every event handler (keydown/input events for input directive, change event for select directive, etc) and some other cases.

参见小例子.尽管更改发生在其他范围内,但似乎 ngRepeat 会在每次按键时重新计算和重绘.

See small example. Seems that ngRepeat is recalculated and redrawn on every keydown despite the fact that changes occur in the other scope.

了解这种决定的理由会很有趣.

It would be interesting to know rationale for such decision.

推荐答案

有 AngularJS 作者对此会很棒,但我相信 $digest() 需要在 $rootScope 上调用,因为在中继器可以触发更改在其他作用域(甚至 $rootScope)中有副作用.

Would be great to have AngularJS authors on this but I believe that the $digest() needs to be called on the $rootScope since changes triggered in a repeater's can have side-effects in other scopes (even the $rootScope).

问题是在子作用域中触发的方法可以影响父作用域中的对象(因为子作用域从父作用域继承).因此,即使子作用域中定义的函数无法修改父作用域中的对象引用,它们仍然可以修改父作用域中定义的对象中的值.

The thing is that methods triggered in child scopes can influence objects in parent scopes (since child scopes inherit from parent ones). So, even if functions defined in child scopes can't modify object references from a parent scope they still can modify values in objects defined in a parent scope.

上面的内容可能听起来有点神秘,所以让我们考虑一个(有点人为的)带有项目列表的示例:

The above might sound a bit cryptic so let's consider an (a bit artificial) example with a list of items:

$scope.items = [{name: 'foo', value:0}, {name: 'bar', value:0}, {name: 'baz', value:0}];

现在,让我们使用 ng-Repeat 来显示上面的列表,假设点击一个项目应该增加 other 项目的值(再一次,这个例子有点人为,但重点是这是在一个范围内触发的操作可能会在其他范围内产生副作用).它可以是这样的:

Now, let's use ng-Repeat to display the above list and let's say that clicking on a item should increment a value of other items (once again, the example is a bit artificial but the point here is that an action triggered in one scope can have side effect in other scopes). It could go like this:

$scope.incOther = function(item) {
        for (var i=0; i<$scope.items.length; i++){
            if ($scope.items[i] !== item){
                $scope.items[i].value++;
            }
        }
    };

示例函数将修改其他范围和 AngularJS 中的值 - 显示正确的结果 - 需要评估父范围中的观察者(直到 $rootScope 因为我们不知道对象在哪里定义).

The example function would modify values in other scopes and AngularJS - to display correct results - need to evaluate watchers in parent scopes (up to the $rootScope since we don't know where an object was defined).

这里是完整的 jsFiddle 说明:http://jsfiddle.net/pkozlowski_opensource/Z6e5g/3/

Here is the complete jsFiddle illustrating this: http://jsfiddle.net/pkozlowski_opensource/Z6e5g/3/

其实上面的jsFiddle也在$rootScope中包含了一个对象来说明观察者的评估确实需要从最顶层开始.

In fact the above jsFiddle also includes an object in a $rootScope to illustrate that the watchers evaluation really needs to start at the very top.

这篇关于为什么 Scope.$apply() 调用 $rootScope.$digest() 而不是 this.$digest()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆