【问题标题】:$watch is triggered directly after init, why?$watch在init之后直接触发,为什么?
【发布时间】:2013-04-08 08:59:42
【问题描述】:

为什么$watch 在页面加载后直接触发,我该如何防止这种情况发生?

http://jsfiddle.net/dcSRu/2/

function MyCtrl($scope) {
    // Init scope vars
    $scope.data_copy = {};

    // If data_copy changes...
    $scope.$watch("data_copy", function(newValue, oldValue) {

        alert("$watch triggered!");

    }, true);
}

【问题讨论】:

  • 如果您有一个控制器或指令在页面加载后的某个时间启动,也会出现这种情况。

标签: angularjs


【解决方案1】:

在第一次运行时,两个值(newValueoldValue)是相等的,因此您可以通过检查是否相等来轻松地将其转义:

$scope.$watch("data_copy", function(newValue, oldValue) {
  if(newValue === oldValue){
    return;
  }
  alert("$watch triggered!");
});

PLUNKER

【讨论】:

  • 啊,谢谢!但是我真的可以用 === 比较这两个对象吗,我不应该使用下划线的 _.isEqual(newValue, oldValue) 之类的东西吗?
  • 可能,但我已经使用了下划线,所以我改用它,效果很好。
  • @tidelipop 为什么需要 _.isEqual,对于 $watch init,newValue oldValue 将是相同的。你的情况的初始值是多少?
  • 如果newValue === oldValue,为什么$watch 甚至会触发? $watch 专门设计用于在不相等时触发。
  • @poshest +1 - 是的,为什么有必要这样做?
【解决方案2】:

将 $watch 函数包装成 Angular 就绪函数。

angular.element(document).ready(function() 
{ 
  $scope.$watch("data_copy", function(newValue, oldValue) {
    alert("$watch triggered!");
  }, true);
})

当角度加载页面时。它改变了值并触发了 $watch。

【讨论】:

    【解决方案3】:

    这里已经有一个很好的讨论:

    How do I ignore the initial load when watching model changes in AngularJS?

    $scope.$watch('fieldcontainer', function (new_fieldcontainer, old_fieldcontainer) {

    if (typeof old_fieldcontainer === 'undefined') return;

    // 此处处理更改对象的其他代码。

    });

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-20
      • 2012-10-05
      • 2018-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多