【问题标题】:AngularJS watch an object property in an object arrayAngularJS 监视对象数组中的对象属性
【发布时间】:2014-07-22 00:18:29
【问题描述】:

我的控制器中有这个data

    $scope.data = {
        home: {
            baseValue: "1",
            name: "home"
        },
        contact: {
            baseValue: "2",
            name: "contract"
        }
     // a lot more options
    };

有一些像这样的html:

<section class="content row" ng-repeat="item in data">
   {{item.name}}
   ....
</section>

现在,我想知道 baseValue 何时更改,但由于我在数据变量中使用了对象,我无法以更简单的方式 watch 属性。

我尝试过类似的方法,但我必须循环所有数组

$scope.$watch('data', function (newValue, oldValue, scope) {
 // some code to compare the tow arrays, line by line
}, true);

如何做一个更简单的$watch 以仅知道baseValue 何时更改?

类似问题:

更新 1

我可以为每个对象添加一个单独的手表,以了解 baseValue 何时更改,但如果我有一个 n 数量的对象,而不仅仅是本示例中的几个对象,那就不好了

$scope.$watch('data.home', function (newValue, oldValue, scope) {
 // do some stuff with newvalue.baseValue
}, true);

$scope.$watch('data.contact', function (newValue, oldValue, scope) {
 // do some stuff with newvalue.baseValue
}, true);
... // Adds more individual `watch`

【问题讨论】:

  • 您只想知道baseValue 何时发生变化,但又不想为其添加单独的手表?
  • 关于你的更新1,你能定义“不好”吗?
  • 使用property descriptors,然后回退到*Timeout 怎么样?
  • 你需要知道旧值吗?或者您只需要注意变化?
  • 还是 $watchGroup ? $watch() 的一个变体,它监视一组 watchExpressions。如果集合中的任何一个表达式发生更改,则执行侦听器。

标签: javascript angularjs


【解决方案1】:

根据您的问题,您可以使用 ngChange 观察baseValue 的变化并触发该功能。

HTML

<section class="content row" ng-repeat="item in data">
    Name: {{item.name}} <br/>
    BaseValue: <input type="text" ng-model="item.baseValue" ng-change="baseValueChange(item.baseValue)"/>
</section>

控制器

$scope.baseValueChange = function(baseValue) {
    console.log("base value change", baseValue);
}

如果你有更复杂的版本可以获取oldValue和newValue,可以参考这个plunkr - http://plnkr.co/edit/hqWRG13gzT9H5hxmOIkO?p=preview

HTML

<section class="content row" ng-repeat="item in data">
    Name: {{item.name}} <br/>
    BaseValue: <input type="text" ng-init="item.oldBaseValue = item.baseValue" ng-model="item.baseValue" ng-change="baseValueChange(item.oldBaseValue, item.baseValue); item.oldBaseValue = item.baseValue"/>
</section>

控制器

$scope.baseValueChange = function(oldVal, newVal) {
    console.log("base value change", oldVal, newVal);
}

【讨论】:

  • 这对我有用,但不是真的使用ng-change 会影响性能吗?这是因为该函数不仅会在值更改时执行。出于这个原因,最好使用wath 以确保仅在更新数据时执行该函数。对吗?
  • 我认为与观看相比没有太大区别。您可能想比较 ng-change 和 watch 之间的侦听器注册数。我认为是一样的。
  • 我同意 +Coyolero。 @Jerska 提供的解决方案更适合我的问题
  • 我认为这不是一个好的答案,因为它只会在来自输入控件而不是来自代码的更新时触发
【解决方案2】:

您可以查看对象属性。
所以你可以做类似的事情

for(var key in $scope.data) {
  if($scope.data.hasOwnProperty(key)) {
    $scope.$watch("data['" + key + "'].baseValue", function(val, oldVal) {
      // Do stuff
    });
  }
}

未经测试,但想法很简单。

【讨论】:

  • 前两天刚开始学习AngularJS。到目前为止我喜欢它。这个解决方案正是我所需要的。我注意到ng-change 指令仅适用于通过与绑定输入(在我的情况下为复选框)交互而更改的值。当数组的元素 baseValues 发生变化时,我想做一些事情,无论它们是从绑定输入更改还是通过编程切换它们。
  • 如果物品来来去去,您还应该删除过时的观察者:var w = $scope.$watch(...);,稍后只需调用w(); 取消注册。
  • $scope.$watch("data[" + key + "].baseValue" .....) 对我不起作用,但 $scope.$watch("data['" + key + "'].baseValue" .....) 对我有用
  • 只是为了安全,我会使用"data[" + JSON.stringify(key) + "].baseValue" 而不是"data['" + key + "'].baseValue"
  • @Hashbrown 同意。我觉得如果你不知道这个转义字符串的技巧,它最终可能会更加混乱,所以我不会改变答案,但希望你的评论会被点赞并且很容易看到。
【解决方案3】:

在这种情况下,无法避免使用多个手表,另一种方法是使用$watchCollection 来观察对象值数组,您可以使用Object.values 函数获取此数组。

scope.$watchCollection(function() {
    return Object.values(obj);
}, function(newValues, oldValues) {
    // now you are watching all the values for changes!
    // if you want to fire a callback with the object as an argument:
    if (angular.isFunction(scope.callback())) {
        scope.callback()(obj);
    }
});

【讨论】:

    【解决方案4】:

    我用这个解决方案解决了:

    $scope.updateFields= function(){
        angular.forEach($scope.fields,function (value, key) {
            value.title = value.title.toLowerCase().replace(/\s+/g,'');
        })
    };
    $scope.$watch('fields', $scope.updateFields, true);
    

    【讨论】:

      猜你喜欢
      • 2017-11-22
      • 1970-01-01
      • 1970-01-01
      • 2017-11-08
      • 2017-11-08
      • 2015-01-04
      • 1970-01-01
      • 2016-08-12
      • 2013-06-29
      相关资源
      最近更新 更多