【问题标题】:Trigger function when property value change of array of objects对象数组属性值改变时触发函数
【发布时间】:2016-08-31 05:15:13
【问题描述】:

以下是我的对象数组的示例。

$scope.arr = [{"A":"a","B":"b"},{"A":"c","B":"d"},{"A":"e","B":"f"},{"A":"g","B":"h"}];

现在我想在属性“A”值发生变化时触发一个函数。基本上是用 not empty 值获得“A”的计数。以下是需要触发的示例场景。

  • 如果新添加到数组的对象的“A”值发生变化。
  • 如果在属性“A”包含值的情况下删除对象。
  • 如果将值添加到对象中的空“A”
  • 如果对象中的“A”现有值被清空

我已经阅读了 Angular watch 文档,这是一个可能的解决方案。但我的问题是如何在数组的 any object 中观察 specific property("A")

感谢任何帮助。

如果在 Angular 中没有可能的解决方案,是否有使用 underscore.js 的替代解决方案?

【问题讨论】:

    标签: javascript angularjs arrays underscore.js


    【解决方案1】:

    对于 AngularJS,有 $scope.$watch:

    $scope.$watch("arr",function (newVal,oldVal){
        console.log("value has changed from "+oldVal+" to "+newVal);
    },true);
    

    但这太贵了。

    对于 vanilla Javascript,这里有一个名为 object.watch 的非标准实现,借用自 here

    /*
     * object.watch polyfill
     *
     * 2012-04-03
     *
     * By Eli Grey, http://eligrey.com
     * Public Domain.
     * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
     */
    
    // object.watch
    if (!Object.prototype.watch) {
        Object.defineProperty(Object.prototype, "watch", {
              enumerable: false
            , configurable: true
            , writable: false
            , value: function (prop, handler) {
                var
                  oldval = this[prop]
                , newval = oldval
                , getter = function () {
                    return newval;
                }
                , setter = function (val) {
                    oldval = newval;
                    return newval = handler.call(this, prop, oldval, val);
                }
                ;
    
                if (delete this[prop]) { // can't watch constants
                    Object.defineProperty(this, prop, {
                          get: getter
                        , set: setter
                        , enumerable: true
                        , configurable: true
                    });
                }
            }
        });
    }
    
    // object.unwatch
    if (!Object.prototype.unwatch) {
        Object.defineProperty(Object.prototype, "unwatch", {
              enumerable: false
            , configurable: true
            , writable: false
            , value: function (prop) {
                var val = this[prop];
                delete this[prop]; // remove accessors
                this[prop] = val;
            }
        });
    }
    

    【讨论】:

    • 感谢@Dustin 的回复。虽然这个(object.watch)不能在我的场景(生产环境)中使用。
    • 是的。但正如你所说,这是一项昂贵的操作。打算寻找替代方案而不是 $watch。感谢@达斯汀的支持
    【解决方案2】:

    可以使用$watch来完成。

    例如:

    $scope.$watch("arr",function (newVal,oldVal){
         angular.forEach(newVal,function (val,index){
             if(oldVal.indexOf(val)== -1){
                     //your code
                  }
            }) 
    
    },true);
    

    这里的第三个参数“true”用于深度检查。

    【讨论】:

    • 是的,但是如果数组中的其他值发生变化,这将触发。在我的示例中,即使属性“B”发生任何变化,这也会触发。
    • 如果整个数组中存在相同的字符变化,这将不起作用。然而,这种操作成本很高。因此,我将寻找替代方法来获取计数,而不是使用 $watch。感谢@Ved 的支持
    • 完成后请更新。我也会在空闲时间检查更好的解决方案
    猜你喜欢
    • 1970-01-01
    • 2023-04-02
    • 2018-09-20
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多