Getter & poseur de soutien avec ng-model en AngularJs

J'essaie d'obtenir des getter/setter de soutien pour les ng-modèle de mise en œuvre d'une directive qui va prendre soin d'obtenir et de définir les valeurs de/à partir de la vue/modèle. Je suis presque là, mais j'arrive à la fin de l'infinie $digest boucles.

L'idée est de définir ng-model="$someFieldToStoreInTheScope", et puis avoir les getter/setter de la directive faire les mises à jour entre le champ et le getter/setter fonctions.

J'utilise $regarder pour mettre à jour le modèle à l'aide de l'incubateur expression lorsque le ngModelController met à jour le champ dans le champ d'application, et une autre montre de mettre à jour ce champ lors de la lecture des modifications de l'expression.

Jeter un oeil à: 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>

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);
}

J'ai mis un setInterval() dans mon code pour modifier le modèle et voir si elle se propage correctement dans la vue.

Aucune idée pourquoi il y a une infinité de digérer la boucle, et comment le supprimer?

Est-il question?
Oui, la question est qu'il ne fonctionne pas bien à cause de l'infinie digérer boucle. Pourquoi est-ce que la boucle là et comment l'enlever?
L'infini digérer boucle semblent être causée par angularjs avoir un moment difficile la propagation de la nouvelle valeur partout avant qu'il se propage à l'ancienne valeur, dans la même boucle. Je pouvais briser la boucle en ajoutant les appels à ngModelCtrl.$setViewValue() et ngModelCtrl.$render() dans le updateViewValue() fonction (Violon: jsfiddle.net/BDyAs/12), mais il serait intéressant de savoir plus précisément ce qui se passait, et si la façon dont je me suis cassé la boucle est la meilleure façon de le faire.
Je pense que la boucle infinie est parce que sur changeValue la montre est l'appel de la méthode de jeu qui, en fait, c'est de modifier le modèle... de sorte que la montre est de nouveau appelée. Peut-être que vous pouvez essayer quelque chose comme "si réel!=nouveau --> mise à jour d'autre --> ne rien faire".

OriginalL'auteur sboisse | 2014-01-22