Angularjs ng-model绑定行为

时间:2014-02-26 19:00:50

标签: angularjs angularjs-directive

我正在编写一个AngularJS指令,并希望将ng-model值绑定到控制器中的对象数组。当数组中的任何内容发生更改时,我希望在指令链接中使用$ render。实际上,只有在更改对数组的引用时才会触发$ render。这是为什么这是ngModelController的预期行为?

下面的代码演示了这种行为以及这个小提琴:http://jsfiddle.net/HandyManDan/RCctF/

<div ng-app="tryApp">
    <div ng-controller="MyCtrl">
        <div> Bound in controller: {{modelVals[0].val}}</div>
        <div> Bound in directive: <span my-dir="" ng-model="modelVals"></span></div>
        <button ng-click="lftBtn()">Mod deep</button>
        <button ng-click="rtBtn()">Mod ref</button>        
    </div>
</div>

myApp.controller('MyCtrl', function($scope) {
    $scope.modelVals = [{val:'val init'}];
    $scope.lftBtn = function() {
        $scope.modelVals[0].val = 'val change deep';
    };

    $scope.rtBtn = function() {
        $scope.modelVals = [{val:'val change ref'}];
    };

});

myApp.directive('myDir', function() {
    return {
        restrict: 'A',
        priority: 1,
        require: 'ngModel',
        link: function(scope, element, attr, ngModel) {
            ngModel.$render = function() {
                element.find('*').remove();
                var el = angular.element("<span>" + ngModel.$modelValue[0].val + "</span>)");
                element.append(el);
            };
        }
    };
});

2 个答案:

答案 0 :(得分:1)

尝试重写您的指令,如下所示:

myApp.directive('myDir', function() {
    return {
        restrict: 'A',
        priority: 1,
        scope: {
            'ngModel': '='
        },
        template: "<span>{{ngModel[0].val}}</span>"
    };
});

演示:http://jsfiddle.net/qwertynl/RCctF/16/

答案 1 :(得分:1)

在深入角度源之后,我确定这是预期的行为。它在这里有一些记录http://docs.angularjs.org/api/ng/directive/select

  

注意:ngModel按引用进行比较,而不是值。这很重要   绑定到一个对象数组。

ngModelController为绑定到ng-model的值设置观察程序。随后发射的手表会调用$ render。观察者采用这种形式

  

$ watch(watchExpression,[listener]);

这种形式的手表仅限于参考更改。

要实现此功能,当指令在对象值更改时获取事件时,需要使用以下形式在ng-model绑定值上设置自己的监视:

  

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

将objectEquality设置为true表示对象值比较。

不幸的是,使用$ watch而不是$ render会绕过ngModelController的格式化程序/验证程序链。