使用$ watch和$ emit更新AngularJS中的模型对象

时间:2014-03-07 14:33:39

标签: angularjs

在我们的应用程序中,我们有一个相当复杂的模型对象,通过对后端的多次调用进行初始化。我们已经完成了自己的“脏”检查实现,即我们监视模型对象的任何更改,并且只有在我们知道模型对象在开始初始化之后才真正做出更改时,才为用户提供保存更改的机会。

{dirty}标志由$watch函数自动引发,该函数监视模型对象中由于用户操作而可能发生变化的部分。在我们完成初始化之后,我们还有一个清除标志的功能(这当然会改变模型的状态并触发观察者),通过$emit调用实现。

因此,我们的想法是遵循以下步骤:

  1. 通过多次调用后端来初始化模型
  2. 清除“脏”标志
  3. 注意模型对象的更改,如果有的话,请举起标志
  4. 但是,现在我们遇到的问题是模型似乎在初始化之后立即被修改。如果我已正确跟踪问题,则会发生这种情况,因为在$emit启动之前会运行$watch清除标记的调用。

    在观察者被调用之后,确保标志被清除的最佳方法是什么?

    此外,这个问题只出现了一段时间,可能与我们升级到AngularJS 1.2有关 - 但这可能只是巧合。

    编辑:标记清除调用的侦听器使用$evalAsync推迟更改,如下所示:

    $scope.$on('resetModelChangeCounter', function(event) {
      event.targetScope.$evalAsync(function() {
        ourModel.setUnchanged();
      });
    });
    

    编辑#2:以下是显示行为的小提琴:http://jsfiddle.net/LVrVj/1/

1 个答案:

答案 0 :(得分:1)

查看代码,你基本上会触发AngularJS必须处理的两件事:信号和手表。

$scope.exampleModel.internalObject.secondKey = "anotherValue";
// this is initialization, so we don't want the change to enable saving
$scope.$emit('resetModelChangeCounter');

您是否期望这些事件以触发它们的顺序发生?我不相信这种假设,在这种情况下,摘要周期似乎在信号处理之前触发了手表。

无论如何,你可以将信号包裹在一个新的超时中,并在消化周期结束并且手表被触发后处理。

我在这里更新了小提琴: http://jsfiddle.net/LVrVj/2/