Reputation: 673
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
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