AngularJs directive: call method from parent scope within template
One way would be to call the functions using $parent
.
<button ng-show="editModel" ng-click="$parent.cancelProfile(); editModel=false">b3</button>
Another way (and probably the better way), is to configure your directive's isolated scope to contain references to those controller functions:
app.directive('editButton', function() {
return {
restrict: 'E',
templateUrl: 'editbutton.tpl.html',
scope: {
editModel: '=ngEdit',
updateProfile: '&',
cancelProfile: '&'
}
};
});
Then you pass the functions in via HTML:
<edit-button ng-edit="editing.section1" update-profile='updateProfile()' cancel-profile='cancelProfile()'></edit-button>
Will Durney
Updated on June 26, 2022Comments
-
Will Durney almost 2 years
I'm pretty new to Angular directives, and I'm having a lot of trouble getting this to do what I want. Here's the basics of what I have:
Controller:
controller('profileCtrl', function($scope) { $scope.editing = { 'section1': false, 'section2': false } $scope.updateProfile = function() {}; $scope.cancelProfile = function() {}; });
Directive:
directive('editButton', function() { return { restrict: 'E', templateUrl: 'editbutton.tpl.html', scope: { editModel: '=ngEdit' } }; });
Template (editbutton.tpl.html):
<button ng-show="!editModel" ng-click="editModel=true"></button> <button ng-show="editModel" ng-click="updateProfile(); editModel=false"></button> <button ng-show="editModel" ng-click="cancelProfile(); editModel=false"></button>
HTML:
<edit-button ng-edit="editing.section1"></edit-button>
If it's not clear, I want the
<edit-button>
tag to contain with three different buttons, each interacting with whatever scope property is passed intong-edit
. When clicked, they should change that property then call the appropriate scope method.The way it is now, clicking the buttons correctly changes the values of
$scope.editing
, but theupdateProfile
andcancelProfile
methods don't work. I may be way off base on how to use directives properly, but I'm having trouble finding an example online to help me accomplish what I'm trying to do. Any help would be appreciated. -
Will Durney almost 10 yearsGreat, thanks. I'm inclined to use your first example, since the two methods will always be the same across directives and it will reduce extraneous html. What makes you say that the second way is the "better way?"
-
Jerrad almost 10 years@futurityverb, The second method is more general. If you want an instance of the directive with slightly different behavior, you can just pass in a different method that should be called. Also, if you start nesting your directive inside other directives,
$parent
may no longer refer to the controller scope, but some other intermediary scope. -
Alex McCabe about 8 yearsPushed me in the right direction, but what if I want to pass arguments to the methods using your second example?
-
Jerrad about 8 yearsPass your argument in as an object. Something like this:
update-profile='updateProfile({message: testMessage})'
.