Two way binding between controller and child directive

by Ahmad Baktash Hayeri

HTML

<div ng-app="app">
  <div ng-controller="ctrl">
    Flag in controller : {{ flag }}
    <div id="dir-wrapper">

    </div>
  </div>
</div>

CSS

button {
  border: 2px solid gray;
  background: #009999;
  color: black;
}

button.enabled {
  background: yellow;
}

JavaScript

angular.module('app', [])
  .controller('ctrl', function($scope, $compile, $timeout, $interval, randomPromise) {
    var el = angular.element('<my-dir />'),
      wrapper = document.querySelector('#dir-wrapper');
    angular.element(wrapper).append(el.attr('flag', 'flag'));
    $compile(angular.element(wrapper).contents())($scope);


    var promise = randomPromise.getAPromise();

    promise.then(function(value) {
      $scope.flag = !$scope.flag ? true : false;
    });
    
    $scope.$watch('flag', function(newValue){
    	console.log('Watching flag, set to: ' + newValue);
    })
  })
  .directive('myDir', function() {
    return {
      restrict: 'E',
      scope: {
        flag: "="
      },
      controller: function($scope) {
        $scope.toggleFlag = function() {
          $scope.flag = !$scope.flag ? true : false;
        }
      },
      link: function(scope, iElement, attrs) {
        //console.log(scope.flag);
      },
      template: '<p>Flag in directive: {{ flag }} </p><button ng-class="flag? \'enabled\': \'\'" ng-disabled="!flag">I am {{ flag ? \'ENABLED\' : \'DISABLED\' }}!</button><button ng-click="toggleFlag()">Toggle Flag</button>'
    };
  })
  .factory('randomPromise', function($q, $timeout) {
    return {
      getAPromise: function() {
        var deferred = $q.defer();
        $timeout(function() {
          deferred.resolve(true);
        }, 3000);
        return deferred.promise;
      }
    };
  })