I am using AngularJS and I have a directive which has its own Controller. It inherits the scope of the Parent Controller.
As an example, consider the following:
function ParentCtrl() {
$scope.aMethod = function() {
// DO SOMETHING
};
}
function ChildCtrl() {
$scope.bMethod = function() {
// DO SOMETHING ELSE
}
}
Now, $scope.aMethod
of ParentCtrl() is triggered by a ng-click directive. What I want to do is call $scope.bMethod
of ChildCtrl(). How can I do it?
EDIT: Some more information. The template associated with the ParentCtrl has a button and multiple directives. Each directive loads a form with different sets of inputs. When the button in the ParentCtrl Template is clicked, the directives are loaded one after another by means of ng-switch on
and ng-switch-when
.
When the user clicks the button, the ChildCtrl which belongs to the directives is meant to store the data in their respective forms.
Thus, when the button is clicked:
1. The ChildCtrl saves the model associated with the current directive that has been loaded.
2. The ParentCtrl loads the next directive in the series.ng-click
is bound to the button which is associated with ParentCtrl. But ChildCtrl also needs to do some action (save the form data) when that button is clicked. How does one accomplish that?
Please have a look at the following.
I'm using the concept of $broadcast
.
I have tired to replicate the scenarios you have given like parent controller, child directive with its own controller etc:
var animateAppModule = angular.module('animateApp', [])
animateAppModule.controller('tst', function($scope) {
$scope.test = function() {
$scope.$broadcast('clickMessageFromParent', {
data: "SOME msg to the child"
})
}
}).directive('myDirective', function() {
return {
controller: function($scope) {
},
link: function($scope, element) {
$scope.$on('clickMessageFromParent', function(scopeDetails, msgFromParent) {
//console.log(msgFromParent)
element[0].innerHTML = msgFromParent.data;
})
}
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="tst">
<input type="button" ng-click="test()" value="click" />
<div my-directive="somvalue"></div>
</div>
JSFiddle
This is similar to what rajkamal is saying, in that you'll need to use broadcast... however you'll want to dynamically change the broadcast to target whichever child you need to.
Here is a plunker showing an example
And here's the code:
app.controller('MainCtrl', function($scope) {
// a method that broadcasts to a selected child.
$scope.broadcastToSelectedChild = function (){
$scope.$broadcast('call-' + $scope.broadcastTo);
};
});
app.directive('testDir', function (){
return {
restrict: 'E',
scope: {
'name': '@'
},
template: '<div>{{name}} called: {{called}}</div>',
link: function(scope, elem, attr) {
scope.called = false;
//a child function to call.
scope.childFunction = function (){
scope.called = true;
};
//set up the name to be used as the listened to event.
var removeOn;
scope.$watch('name', function(v) {
if(removeOn) removeOn();
removeOn = scope.$on('call-' + scope.name, function (){
scope.childFunction();
});
});
}
};
});
and here it is in HTML:
<div ng-controller="MainCtrl">
<test-dir name="test1"></test-dir>
<test-dir name="test2"></test-dir>
<test-dir name="test3"></test-dir>
<select ng-model="broadcastTo" ng-options="x as x for x in ['test1', 'test2', 'test3']"></select>
<button ng-click="broadcastToSelectedChild()">test</button>
</div>
What I did here is create a mechanism by which I can name my directives, and then broadcast to them by name. If the code isn't self explanatory, let me know. I hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With