使用AngularJs中的ng-model获得getter和setter支持

sbo*_*sse 11 getter setter directive angularjs

我试图通过实现一个指令来获取和设置视图/模型的值,从而获得对ng-model的getter/setter支持.我几乎在那里,但我最终在无限的$ digest循环中.

我们的想法是设置ng-model ="$ someFieldToStoreInTheScope",然后让getter/setter指令在该字段和getter/setter函数之间进行更新.

当ngModelController更新范围中的字段时,我使用$ watch使用setter表达式更新模型,当getter表达式更改时,我使用另一个watch来更新该字段.

看看:http://jsfiddle.net/BDyAs/10​​/

HTML:

<div ng-app="myApp">
<body>
<form name="form">    
    <input type="text" ng-model="$ngModelValue" ng-model-getter-setter="get=getValue();set=setValue($value)"/> {{myDerivedValue}}
</form>
</body>
</div>
Run Code Online (Sandbox Code Playgroud)

JS:

var myApp = angular.module('myApp', []);

myApp.directive(
    {
        'ngModelGetterSetter': function () {
            return {
                require: "ngModel",
                controller: ctrl,
                link:  function(scope, element, attrs, ngModelCtrl)
                {
                    var getterSetterExpression = attrs.ngModelGetterSetter;
                    var tokens = getterSetterExpression.split(";");
                    var getExpression = tokens[0].split("=")[1];
                    var setExpression = tokens[1].split("=")[1];

                    function updateViewValue()
                    {
                        var updateExpression = attrs.ngModel + "=" + getExpression;
                        scope.$eval(updateExpression);
                    }

                    function updateModelValue()
                    {
                        scope.$value = ngModelCtrl.$viewValue;
                        scope.$eval(setExpression);
                    }

                    updateViewValue();    

                    scope.$watch(getExpression, updateViewValue);
                    scope.$watch(attrs.ngModel, updateModelValue);
                }
            };
        }
    });

function ctrl($scope) {
    $scope.getValue = function ()
    {
        return $scope.myValue;
    }

    $scope.setValue = function (val)
    {
        $scope.myValue = val;
        $scope.myDerivedValue = $scope.myValue * 2;
    }

    $scope.setValue(5);

    setInterval(function () { $scope.setValue($scope.getValue() + 1); $scope.$apply(); }, 1000);
}
Run Code Online (Sandbox Code Playgroud)

我在我的代码中放了一个setInterval()来修改模型,看看它是否在视图中正确传播.

知道为什么有一个无限的摘要循环,以及如何删除它?

sbo*_*sse 8

注意 AngularJs 1.3现在支持ng-model的Getter/Setter.有关更多信息,请参阅http://docs.angularjs.org/api/ng/directive/ngModelOptions.


我可以用额外的调用打破无限循环

ngModelCtrl.$setViewValue()
Run Code Online (Sandbox Code Playgroud)

ngModelCtrl.$render()
Run Code Online (Sandbox Code Playgroud)

在事件处理程序中.不知道这是否是最佳方式.

请参阅小提琴:http://jsfiddle.net/BDyAs/12/

编辑:

我进一步改进了代码

http://jsfiddle.net/BDyAs/15/

通过在getter和setter的单独的指令中分离指令.