I have a controller that is the controller for my page but i was wondering if its possible to have a AppLevel controller i.e. something that is accessible from every page... so each page would actually have more than 1 controller assigned.
I know i can probably do this with a service and inject the service but I was hoping for some kind of applevel controller that can be assigned.
If this possible, how would i communicate between the 2? I presume using dependency injection and just pass the applevel controller to my main page?
Anyone have an idea about this?
thanks
AngularJS leverages JavaScript prototypical inheritance in order for scopes to access properties on the parent scope. You can define the controllers nested in the HTML and access the parent from the child. However I would strongly urge you not to rely on this fact for your 'AppCtrl'. In some cases the scope you are working on will be isolated and will not be a part of the inheritance hierarchy that has access to the AppCtrl's scope.
I would suggest creating a service for this, or you could use pub/sub with $rootScope.$on and $rootScope.$broadcast.
To show the service example I'll use the words shellCtrl and shell service instead of app to make the example a little clearer.
The 'shell' service's job is to allow any other controller, directive or service in your app to interact with the shellController, and therefore the host view container.
<div ng-app="myApp" ng-controller="ShellCtrl">
<div ng-controller="SomeOtherCtrl"></div>
</div>
// parent controller defined on the same element as ng-app
function ShellCtrl($scope, shell) {
// I've just made the shell accessible to the $scope of shellctrl, but you can do
// this in various ways.
$scope.shell = shell;
}
// any other controller
function SomeOtherCtrl($scope, shell) {
shell.setTitle('Some title');
}
// basic example of the shell service
angular.module('myApp').factory('shell', function () {
return {
title = 'No title set',
setTitle = function (title) {
this.title = title;
}
}
});
Now you can set properties on the parent controller in a detached fashion without relying on the scope hierarchy.
When you have a child controller in Angular it inherits from the parent scope. So if you have one top level controller that contains functions that some descendant controller doesn't have then the top level function (or scope object) will be referenced. If one of the child controllers defines a local version of the function (or property on the scope) then it will no longer inherit from it's parent controller.
The Fiddle: http://jsfiddle.net/Y9yEQ/
The HTML
<div ng-app="myApp" ng-controller="TopLevelCtrl">
<button ng-click="testing()">Yo top level!</button>
<button ng-click="testing2()">Yo top level 2!</button>
<div ng-controller="ChildCtrl">
<button ng-click="testing()">Yo child!</button>
<button ng-click="testing2()">Yo child2!</button>
</div>
</div>
The JS
angular.module("myApp",[]).controller("TopLevelCtrl", function($scope){
$scope.testing = function() {
alert("just testing");
}
$scope.testing2 = function() {
alert("just testing parent");
}
}).controller("ChildCtrl", function($scope){
$scope.testing2 = function() {
alert("just testing child");
}
})
If you need to share some data between multiple controllers (since controller instances may be created or destroyed to support views as they are added/removed) you'll want to use a service. If you have a strict structure for your controllers you can $emit to bubble an event up scopes or $broadcast to send events down through scopes.