Calling of one controller from another - angularjs

While loading I am calling one controller, however I am using ng-include to import another HTML page in the main HTML page.
I want to call ng-controller of included page.(How to call a child controller from a parent controller using ng-init)

You need not call it seperately. Just add 'ng-controller' directive on the 'ng-include' element and assign its controller as shown below:
<div ng-include="template.url" ng-controller="YourController"></div>

The best way to do this is to have the parent Controller broadcast an event that the child scope will register:
.controller("ControllerParent", [$scope, function($scope) {
$scope.alertChild = function() {
$scope.$broadcast("custom-event", data);
};
});
.controller("ControllerChild", [$scope, function($scope) {
$scope.$on("custom-event", function(event, data) {
//do something with event
};
});

Related

AngularJS: How to pass button clicked ng-model value from one controller to another controller

I have a button where I am passing the ng-model value as a parameter to its ng-click function, Now after this ng-click function executes, I would like to send that ng-model value to another controller, how can I do this using angular?
Is there a way to do this?
There are many ways to communicate between controllers.
use $broadcast like mentioned in other comments, or
use $emit
Something like this...
function Controller1($scope)
{
$scope.$on('myEvent', function(event, args) {
// do the event
});
// another controller, directive
}
function Controller2($scope)
{
$scope.$emit('myEvent', args);
}
1.In first Controller, you can do:
$rootScope.$broadcast('eventName', value);
and listen to the event in second Controller:
$scope.$on('eventName', function (event, value) {//your code});
2.In first controller assign the values to the $rootScope variable then access from the other controller.for example
in first controller
$rootScope.TestValue="10";
in second controller
$scope.receiveValue=$rootScope.TestValue;
3.AngularJS- How to pass data from one controller to another on ng-click()?
Use angular service to communicate between 2 controller.
Watch this Video
Yes $broadcast will work for you.
Here are some essential parts:
Create service that implements message bus functionality (e.g. $scope instance)
Inject service to both controllers
$broadcast() event from one controller
subscribe to event with $on() in another
Example:
HTML
<div ng-controller="ctrl1 as ctrl1">
<button ng-click="ctrl1.hello()">Say hello</button>
</div>
<div ng-controller="ctrl2 as ctrl2">{{ctrl2.messages}}</div>
JavaScript
angular.module('app', [])
.service('messageBus', ['$rootScope', function($rootScope) {
return $rootScope.$new();
}])
.controller('ctrl1', ['messageBus', function(messageBus) {
this.hello = function() {
messageBus.$broadcast('hello', 'Hi! '); // <= send message
}
}])
.controller('ctrl2', ['messageBus', function(messageBus) {
var ctrl2 = this;
this.messages = '';
console.log(messageBus.mb)
messageBus.$on('hello', function(evt, msg) { // <= receive message
ctrl2.messages += msg;
});
}]);

Angularjs: How to build a controller reuseable?

I have an application with some controllers that have the same functions as: InitMenu, GetData, Search, Paging, ..
How can I build a generic controller with the main functions: InitMenu, GetData, Search, Paging, .. without having to write in each specific controller?
share all the common logic inside a service and inject it inside your controllers.
.service('CommonData, function(){
this.getData = function(){
}
this.InitMenu= function(){
}
this.search= function(){
}
})
otherwise you can make a parent controller and all the child controllers will prototype inherit from the parent scope.
.controller('ParentCtrl', function($scope){
$scope.myObj = {};
$scope.parentMethod = function(){
return myObj;
}
})
.controller('ChildCtrl', function($scope){
var stuff = $scope.parentMethod();
//you can access the parent method in the child template as well
})
<div ng-controller="ParentCtrl">
<div ng-controller="ChildCtrl">
{{parentMethod()}}
//if you use controllAs syntax change it to {{parentCtrlName.parentMethod()}}
</div>
</div>
if you use controllerAs syntax you can access the parent $scope by specifyng the controller name as a scope field in the child controller. e.g $scope.parentCtrlName.parentMethod() and parentCtrlname.parentMethod() in the child template.

Communication between child and parent directive

I'm trying to figure out how to make a child directive communicate with it's parent directive
I basically have this html markup
<myPanel>
<myData dataId={{dataId}}></myData>
</myPanel>
In the myData directive, if there is no data available, I want to hide the myPanel.
In the myData directive controller I've tried
$scope.$emit('HideParent');
And in the myPanel controller I've tried
$scope.$on('HideParent', function () { $scope.hide = true; });
And also
$scope.$watch('HideParent', function () { if (value) { $scope.hide = true; }});
In either situation, the myPanel directive isn't receiving the $emit
You may create controller in myPanel directive.
Then require this controller in myData directive. And when child directive has no data, call controller method to hide parent.
For example in you parent (myPanel) directive:
controller: function($scope, $element){
$scope.show = true;
this.hidePanel = function(){
$scope.show = false;
}
}
In myData directive require this controller:
require:'^myPanel'
And then, call controller function when you need
if (!scope.data){
myPanelCtrl.hidePanel();
}
Look this Plunker example
The answers above where the parent directive's controller is required is a great one if there truly is a dependency. I had a similar problem to solve, but wanted to use the child directive within multiple parent directives or even without a parent directive, so here's what I did.
Your HTML.
<myPanel>
<myData dataId={{dataId}}></myData>
</myPanel>
In your directive simply watch for changes to the attribute.
controller: function ($scope, $element, $attrs) {
$attrs.$observe('dataId', function(dataId) { $scope.hide = true; } );
}
It's explicit and simple without forcing a dependency relationship where one may not exist. Hope this helps some people.

Call function on child state angularjs

In my view have a link that calls a function like: <a href=/albums ng-click='findAll()'>, and it all works fine, but when u type directly to the URL /albums nothing happens, findAll() function doesn't trigger.
My question is, Is there anything that I can do using states in Angular that when this state is executed to automatically call that function findAll() and render the view with the data.
Kinldy Regards,
For this you can add your function to $rootScope. Inject $rootScope for your parent controller.
app.controller('parentCtrl', function($rootScope, $scope){
$rootScope.findAll = function(){
/* your code here */
};
});
<div ng-controller='parentCtrl' ng-init='findAll()'></div> <!-- parent Div -->
or you can use run function
app.run(function($rootScope) {
$rootScope.findAll = function(){
/* your code here */
};
$rootScope.findAll(); // Call when angular bootstrap
});
For both in your child controllers you can use ng-init to call it automatically
<div ng-controller='childCtrl' ng-init='findAll()'></div> <!-- child Div -->

Angular : check in controller if directives link function is called

So, we have a directive grid, which exposes directive controller to the angular controller, so that controller can call functions on directive (just like a form controller).
Now, in my angular controller every thing works as long as I access the directive controller from a callback action eg. some $scope.xx which are called on some event like click or any thing.
But when i try to access the directive controller at controller initialization time, the directive controller is undefined, that means, directives link function is not called yet.
Here's some code
function controller() {
$scope.init = function() {
$scope.grid.search(xx)
}
$scope.init() // this will fail, because $scope.grid is undefined.
$scope.onClick = function() {
$scope.grid.search(xx) // this will work
}
}
is there any other way, other then watching the $scope.grid, to have the $scope.grid.search called on controller initialization
You can just broadcast event from link function in your directive.
<div ng-controller="MyCtrl">
<div abc></div>
</div>
myApp.directive('abc', function($rootScope) {
return {
restrict: "EA",
link: function(scope, element, attrs){
$rootScope.$broadcast("initialize");
}
}
});
function MyCtrl($scope) {
$scope.$on("initialize", function(){
alert("Link function has been initialized!");
});
}
I've created JSFiddle for you.
The problem is that parent controllers are always called before child controllers.
If you want to run code after your child directive is initialized, you can create a directive and put the initialization code inside of its link function.
This works because parent link functions are always called after child link (and controller) functions.

Resources