【问题标题】:Why does binding trigger a $watch although no data was changed?为什么绑定会触发 $watch 虽然没有更改数据?
【发布时间】:2016-06-06 13:41:37
【问题描述】:

我有一个用户正在编辑的范围内的实体。每次修改时,我都想触发一些自定义验证。所以我有:

// validate the position if anything has changed
$scope.$watch("entity", function() {
    if ($scope.entity.Id) {
        $scope.validate();
    }
}, true /* watch "by value" (see: https://docs.angularjs.org/guide/scope#scope-life-cycle) */);

到目前为止一切顺利。现在,由于这是一个具有相当多字段的大实体,因此并非所有字段最初都参与数据绑定。通过使用选项卡控件,用户只能看到部分字段。当用户切换选项卡时,会显示实体的另一部分。

但是,当附加控件绑定到实体的相应字段时,$watch 会被触发,即使绑定不会更改实体上的任何值。

为什么会这样,我该如何预防?

注意: 我认为数据绑定可能会在entity 中添加一些内部$... 字段,但希望这些字段被忽略(至少angular.equals 是这种情况,所以它们可能也应该在$watch 中被忽略,我假设)。

【问题讨论】:

  • 每个观察者都被调用一次进行初始化。
  • @zeroflagL:我只设置了一次$watch

标签: angularjs


【解决方案1】:

$watch 带有对象相等标志true 将旧对象副本的属性与当前对象进行比较。因此,当更改、添加或删除属性名称时,侦听器会触发。您可以尝试以下方法:

$scope.$watch("entity", function(newVal, oldVal) {
    if(Object.keys(newVal).length !== Object.keys(oldVal).length)
        return; //Detect added properties

    if ($scope.entity.Id) {
            $scope.validate();
    }
}, true

【讨论】:

  • 主要问题仍然是:数据绑定为什么要添加、更改或删除属性?
  • 两种可能,要么$scope.entity.someBoundData没有初始化,所以绑定给$scope.entity增加了someBoundData属性,要么没有初始化正确的值,比如空字符串" ",因此在绑定时更新
猜你喜欢
  • 1970-01-01
  • 2013-07-21
  • 2021-11-09
  • 2023-03-07
  • 2020-04-06
  • 1970-01-01
  • 2016-03-10
  • 2016-08-01
  • 1970-01-01
相关资源
最近更新 更多