Search code examples
angularjsangularjs-directiveangularjs-scope

Angularjs directive two way binding does not update html


I created a calendar directive. My intention is when I press the 'Change' button to update calendar date. Although when I inspect the scope, calendarDate is updated, in the markup it remains the same. Any idea what am I doing wrong? Here is the code:

var DailyTimekeeping = TimekeepingsApp.controller('DailyTimekeeping', [
    '$scope', 'UserService', '$http', function($scope, UserService, $http) {
        var self = this;
        self.currentDate = new Date();
        $scope.init = function(userId) {
            self.currentDate = new Date();
        }

    } ]);

 var calendar = TimekeepingsApp.directive('calendar', ['$timeout',    function($timeout) {
return {
    restrict : 'E',
    scope : {
        calendarDate : '=date'
    },
    templateUrl : 'angular/calendar.html',
    link: function (scope, element, attrs) {
        scope.$watch('calendarDate', function() {
            element.on('click', '.change' ,function (e) {
                   alert('Test');
                   scope.calendarDate.setDate(10);
                });
         });

    }
};

And the calendar.html

<div class="container-fluid calendar-component">
<div class="row">
    <div class="col-md-12 text-center calendar-month">
        <span> {{calendarDate}} </span>
    </div>
</div>
<div class="row calendar-day">
    <div class="col-md-12 text-center"> <a class="change"">Change </a></div>
    <div class="col-md-12 text-center day-number">{{calendarDate | date: 'dd'}}</div>
    <div class="col-md-12 text-center day-name">{{calendarDate | date: 'EEEE'}}</div>
</div>

This component is used:

calendar date="dailyTimekeeping.currentDate">


Solution

  • Your problem is that element.on is merely wiring up a callback to be run when an event occurs. Since your callback occurs outside of the normal scheme of Angular behavior, it has no way to know to notice that your scope variable changed (through something called the digest cycle).

    You can fix this by putting the update code inside of a scope.$apply(...) call, as that will tell Angular to run a digest after your code executes:

    ...
    element.on('click', '.change' ,function (e) {
        alert('Test');
        scope.$apply(function() {
            scope.calendarDate.setDate(10);
        });
    });
    ...