为什么在视图更改时$ doCheck会被调用两次,我该怎么办?

时间:2018-12-29 16:26:10

标签: javascript angularjs

在下面的Angular 1.7.5代码中,我使用gg.fields = [ { ... }, {value: "D", display_name: "Nat."}, { "value":"Likes redwine", "display_name":"Trace 2", "servicio_tags":[ "trace" ] } ] //function let traceFieldExists = gg.fields.forEach((field, positionOfTraceField) => { if (field.servicio_tags && field.servicio_tags[0] === 'trace') { return { positionOfTraceField : positionOfTraceField, exists : true }; } else { return {exists : false}; } }); 将文本框连接到某个控制器字段,并在值更改时使用ng-model进行操作。请注意,在我的实际项目中,我正在监视的值是一个对象,每当其任何字段更改时,我都需要找出它,因此我必须使用$doCheck。我知道这对于文本框来说太过分了。

HTML

$doCheck

JS

<div ng-app="app" ng-controller="TheController as ctrl">
    <input ng-model="ctrl.value" />
</div>

每当文本框中的值更改时,您就会看到angular.module("app", []) .controller("TheController", class TheController { constructor() { this.value = ""; } $doCheck() { console.log("check: " + this.value); } } ); 被调用两次(两次都使用新值)。为什么是这样?如何过滤掉“毫无意义的” $doCheck调用,而仅获得值实际更改的调用?

1 个答案:

答案 0 :(得分:1)

$digest循环不断迭代,直到模型稳定为止,这意味着$evalAsync队列为空,并且$watch列表未检测到任何更改。

这意味着$doCheck将至少拨打两次 。一次检测更改,然后再次检测没有新更改。如果有更多更改或功能添加到$evalAsync列表中。它将一次又一次地调用到$rootScopeProvider.digestTtl(limit)设置的限制。

如果检测到更改,则必须存储以前的值以便与当前值进行比较。

this.$doCheck = function() {
    var newValue;
    var oldValue;
    oldValue = newValue;
    newValue = itemOfInterest();
    if (newValue != oldValue) {
       //Code to act on changes
    };
};

有关更多信息,请参见