AngularJS - 当双向绑定值发生变化时,在指令中调用函数

时间:2014-03-04 07:24:59

标签: angularjs angularjs-directive

我有一个指令,所有设置都使用=对属性进行双向数据绑定,我可以看到一切都运行良好。现在,当我的一个绑定属性在父范围内发生变化时,我仍然需要在指令中调用一个函数,而我无法弄清楚如何将其拉出来。

我基本上是在创建一个ui复选框按钮的版本,它可以处理对象数组。您将指令传递给allowed数组(包含所有不同的选项)和applied数组(包含来自allowed的相同对象)。为了检查对象是否在allowed数组中,我有另一个数组,它只是id属性。在指令中,这很有效,但是如果applied数组在指令之外发生更改,则id数组永远不会更新。

指令:

angular.module('MyApp',[])
.directive('btnCheckboxGroup', function(){
    return {
        restrict: 'E',
        // controller: DirCtrl,
        templateUrl: 'btnCheckboxGroup.html',
        scope: {
            allowed: '=',
            applied: '=',
            id: '=',
            title: '='
        },
        link: function(scope, elem, attrs){ 
            scope.abp = [];

            // this works right away, but how do I run it when the parent scope updates it?
            angular.forEach(scope.applied, function(obj){
               scope.abp.push( obj[scope.id] ); 
            });

            scope.addRemove = function(a){
                var index = scope.abp.indexOf(a[scope.id]);

                // doesn't exist, add it
                if(index === -1){
                    scope.abp.push(a[scope.id]);
                    scope.applied.push(a);

                // does exist, remove it
                } else {
                    scope.abp.splice(index, 1);
                    for(var i in scope.applied){
                        if(scope.applied[i][scope.id]==a[scope.id]){
                            scope.applied.splice(i,1);
                            break;
                        }
                    }
                }
            }// end addRemove()

        }
    };
});

JSFiddle

我尝试了很多变体,例如scope.$watchattrs.$observe,并尝试在某一点上尝试与@进行单向数据绑定,并且做了很多事情崩溃。

那么我在这里失踪的神奇是什么?

2 个答案:

答案 0 :(得分:0)

这是你要找的吗?

        scope.$watch(function() {
             return scope.applied.length;   
        }, function(val) {
            console.log(val);
            console.log(scope.applied);
        });

作用域上的数组不会改变,但是它的长度会改变,所以如果你使用$watch的字符串变体,它将不会触发,但使用函数并查看数组的长度将。有关详情,请参阅docs

答案 1 :(得分:0)

您可以将第三个参数传递给$ watch,以更改比较旧值和新值的方式。请参阅Angular docs

$watch(watchExpression, [listener], [objectEquality]); 

如果将其设置为true,它将获取数组内容的更改,而不仅仅是数组引用更改时。这确实会对性能产生影响(取决于阵列的长度)。仅检查数组的长度并不包括元素数量保持不变但元素本身发生变化的情况。

在你的情况下,你需要做这样的事情:

 scope.$watch(
     "applied", 
     function() {
         scope.abp = [];
         angular.forEach(scope.applied, function(obj){
             scope.abp.push( obj[scope.id] ); 
         });
     },
     true);