kidwon
kidwon

Reputation: 4524

Custom attribute two way binding not working

In this example I face 2 problems

https://jsfiddle.net/1g6kvxst/

  1. Obviously <b>{{moo}}</b> isn't updated. Isn't the expression {{moo}} supposed to be 2 way binding ?
  2. And probably because of the first problem my watch expression about directive my-var attr value in link callback isn't updated

What am I missing? Appreciate your kind help.

View

<section ng-app="myApp" ng-controller="myController"> <div my-directive my-var="moo"></div> <span>Result:</span> <b>{{moo}}</b> </section>

Directive

App.directive('myDirective', function () {
    return {
        restrict: 'A',
        scope:{
            myVar: '='
        },
        link: function (scope, element, attrs) {
            scope.$watch(scope.myVar, function() {          
                console.log('my var changed to: ', scope.myVar);
            });
        }
    };
});

Controller

var ctrls = angular.module('controllers',[]);
ctrls.controller('myController', ['$scope', function ($scope) {
    $scope.moo = 0; 
    var t = setInterval(function(){
        $scope.moo++;
    },1000);
}]);

Upvotes: 1

Views: 87

Answers (2)

ms87
ms87

Reputation: 17492

use $interval, not setInterval, angular doesn't run a digest loop when you use setTimeout, and thus your directives scope is not aware of any changes.

Upvotes: 2

devqon
devqon

Reputation: 13997

Angular uses watches to re-evaluate variables in the view. These watches are build in angular's async functions, like $timeout, $http etc. When using the native setTimeout, angular's digest cycle does not pick up that change;

Use angular's $interval service instead of the native javascript interval:

var t = $interval(function(){
    $scope.moo++;
},1000);

Don't forget to inject into the controller:

ctrls.controller('myController', ['$scope', '$interval', function ($scope, $interval) {

To make the $watch work, watch the key and not the object:

scope.$watch('myVar', function() {

JSFIDDLE

Upvotes: 2

Related Questions