Joe
Joe

Reputation: 47659

Two-way binding in an angular directive leads to loop

I have a directive with a select in it. Here is a cut-down example. Note the real code has more moving parts and some logic.

app.directive('numberPicker', function() {
    return {
        restrict: "E",
        scope: {
            number: "=model",
        },
        template: "<select data-ng-model='numberName' data-ng-options='name for name in numberNames' class='form-control'></select>",
        link: function(scope, element, attrs) {
            scope.numberNames = ["Zero", "One", "Two"];

            scope.$watch('number', function(number) {
                scope.numberName = scope.monthNames[number];
            });

            scope.$watch('numberName', function(numberName) {
                scope.number = scope.numberNames.indexOf(numberName);
            });
        }
    };
})

The idea that there is a number in the outer scope which is bound to a select. Binding should work both ways.

The problem is that the $watches trigger each other, leading to strange behaviour.

How should I go about binding the scope to a select via a lookup, and the select back to the scope via a reverse lookup?

Upvotes: 0

Views: 138

Answers (1)

Arun Ghosh
Arun Ghosh

Reputation: 7754

You can use the below logic as a work around, but don't think it is an elegant solution

scope.$watch('number', function(number) {
    if(scope.numberName != scope.monthNames[number]){
        scope.numberName = scope.monthNames[number];
    }
});

scope.$watch('numberName', function(numberName) {
    if(scope.number != scope.numberNames.indexOf(numberName)){
        scope.number = scope.numberNames.indexOf(numberName);
    }
});

Upvotes: 1

Related Questions