Lefka
Lefka

Reputation: 673

Callback method inside angular directive with new scope

I am building a shadow copy directive to allow me to easily discard changes made to an object, and only commit them when a button is pressed. This is working fine but I'm finding that there are certain instances where I want to call a function inside the controller when the data is committed. How do I access a function in the controller from the directive by passing the function as an attribute?

HTML:

<div ng-app="myApp" ng-controller="myCtrl">
  <div my-directive="name" commit-function="saveData()">
    <input type="text" ng-model="name" />
    <button ng-click="commit()">
      Save
    </button>
  </div>
  <span>{{name}}</span>
  <br />
  <span>{{copiedName}}</span>
</div>

Directive:

myApp.directive('myDirective', function() {
  return {
    scope: true,
    link: function(scope, el, att) {
      scope[att.myDirective] = angular.copy(scope.$parent[att.myDirective]);
      scope.commit = function() {
        scope.$parent[att.myDirective] = angular.copy(scope[att.myDirective]);
      }
    }
  }
});

Controller:

myApp.controller('myCtrl', function($scope) {
  $scope.name = 'Frank';
  $scope.copiedName = 'Freddie';

  $scope.saveData = function() {
    $scope.copiedName = $scope.name;
  }
});

I set the commit-function attribute to saveData() and now I want to get the function from that attribute.

I know I can use an isolated scope and set commitFunction: '&' but as I understand it, I then cannot access the commit function of the directive.

Here is a codepen showing what I'm after. I would expect when this is working that saveData has been fired and the display for name and copiedName would match.

Upvotes: 0

Views: 297

Answers (1)

goeldeepika3
goeldeepika3

Reputation: 91

To be able to invoke a method specified in the attribute commit-function, you can use $apply, since the $rootScope is already in progress, you can add $timeout

myApp.directive('myDirective',['$timeout', function($timeout) {
  return {
    scope: true,
    link: function(scope, el, att) {
      scope[att.myDirective] = angular.copy(scope.$parent[att.myDirective]);
      scope.commit = function() {
        scope.$parent[att.myDirective] = angular.copy(scope[att.myDirective]);
        $timeout(function(){
           scope.$apply(att.commitFunction);
        },0);}
    }
  }
}]);

Upvotes: 2

Related Questions