I have this html template into fileA.directive.html:
<md-button ng-click="resetForm()" class="btn btn-primary">Reset form</md-button>
<user-form reset-user-fn=""></user-form>
And into my fileA.directive.js:
app.directive("shopAppFormCustomer", function() {
return {
restrict: "E",
replace: true,
templateUrl: "fileA.directive.html",
scope: {},
controller: [
"$scope",
function($scope) {
$scope.resetForm = function () {
// want to call reset-user-fn here
}
}
]
};
})
Into my fileB.directive.js, I have the userForm
directive
app.directive("userForm", function() {
return {
restrict: "E",
replace: true,
templateUrl: "fileB.directive.html",
scope: {resetUserFn: "=" },
controller: [
"$scope",
function ($scope) {
$scope.resetUserFn = function () {
// reset goes here
}
}
]
}
Here's my question:
How can I trigger the attribute resetUserFn
into my fileB.directive.js into my fileA.directive.js?
Any source or documentation please.
Note: I won't to use custom event if it's possible.
So you want to trigger some method of child directive from parent directive. Unfortunately, AngularJS has no native support for such kind of problem. Here are some workaround for your consideration
- Use built-in event dispatcher, here is a good explanation.
- Component-based $onChanges approach, described here
- Each angular service is a singleton, therefore you can create a service, intended for parent-to-child communication.
Each approach is pretty ugly!
- Event dispatcher - too many events may significantly slow down the application. You may end-up with hundreds of events which is really hard to maintain.
- $onChanges - the code looks ugly, hard to maintain.
- You need a new service for each case, hard to maintain.
I suppose that there are some reasons why it is not natively supported. What if you have two or more <user-form reset-user-fn=""></user-form>
directives under shopAppFormCustomer
parent directive? And you want to call to resetUserFn
of one particlurar userForm
directive, how to distinguish one userForm
from another userForm
?
This was somehow supported in Angualar 2 and higher, but the solution is not perfect either. So you have just to choose which solution from above is less painful for you and deal with it.
You should create a common service so that you can use everything inside the service anywhere you want. In this case, a function that can be used in both fileA.directive.js and fileB.directive.js.
<md-button ng-click="resetForm()" class="btn btn-primary">
Reset form
</md-button>
̶<̶u̶s̶e̶r̶-̶f̶o̶r̶m̶ ̶r̶e̶s̶e̶t̶-̶u̶s̶e̶r̶-̶f̶n̶=̶"̶"̶>̶
<user-form reset-user-fn="resetForm">
</user-form>
The <user-form>
directive assigns the parent scope property resetForm
to a reference to the function. The ng-click
directive invokes that function.
To avoid memory leaks, be sure to null
the property when the isolate scope is destroyed.
app.directive("userForm", function() {
return {
restrict: "E",
templateUrl: "fileB.directive.html",
scope: {resetUserFn: "=" },
controller: function ($scope) {
$scope.resetUserFn = function () {
// reset goes here
};
$scope.$on("$destroy", function() {
$scope.resetUserFn = null;
});
}
}
}