Things in Angular can be injected with dependencies. But, injecting $scope into a directive won't work for example. Is there a concrete list of what is injectable into a controller or what isn't? What is injectable into a directive and what isn't? What is injectable into a service and what isn't? Etc? A comprehensive list of injectable/not injectable all in one place? The docs seems to have this info spread around, but it's hard to navigate.
You can read everything in the docs. In case you mis-typed your controller:
angular.module('app', []).controller('controllerName', ['$scope', function($scope) {
// Your controller logic
}]);
The controller is injectable (and supports bracket notation) with the following locals:
$scope - Current scope associated with the element
$element - Current element
$attrs - Current attributes object for the element
$transclude - A transclude linking function pre-bound to the correct transclusion scope
For more information, see AngularJS Comprehensive Directive API - controller.
Related
I am using angularjs ui tour https://github.com/benmarch/angular-ui-tour
I have successfully installed the directive,
I now want to initialize the directive in my controller when the page is loaded.
On my routes, I have the following code
when('/start', {
templateUrl: 'start.html',
controller: 'startController'
})
On the template start.html, I have the following code
<div ui-tour class="myClass">
So I want to access the tour var of ui-tour scope from startController, how can I do that?
That depends on how directive is defined. Does it create a new scope or not? Is it's scope proto inherited or isolated one. The simplest solution is to make your directive not create a new scope but use parent's one. If it is the same scope, simply call a function in the directive from parents controller like you would do for a function in that controller.
For more info about why is not a straightforward answer and what are the options when defining directives concerning scope, I find this well explained on the following link:
directives and scopes
Taking a look at the documentation, it looks like it's possible. Via the uiTourService documentation
yourModule.controller('startController',
['$scope', 'uiTourService', function($scope, uiTourService) {
var myTour = uiTourService.getTour();
}]);
Problem Related codepen
I declared $rootScope.myproperty in main controller and it can be accessed in other controllers.
But in one of the controller I have to inject $rootScope as I used $watch. Then when I check back $rootScope.myproperty it became undefined. Strange why would this happens?
It was happening because you were using $rootScope as a variable and assigning an object to it
$rootScope = { myproperty: 'root abc' };
This is wrong. Instead you should add attributes to it as below and it will work:
$rootScope.myproperty = 'root abc';
I have updated the codepen and its working : http://codepen.io/anon/pen/RaeyJm
Working Demo
The problem is you have injected $rootScope into AttendeesCtrl controller. You don't need to inject $rootScope into a controller. When you inject $scope, you automatically get access to anything defined in $rootScope due to the prototypal inheritance of JavaScript. So AttendeesCtrl controller should look like this:
.controller('AttendeesCtrl', function($scope) {
//I used $watch and $rootScope somehere so I have to inject $rootScope in this controller
$scope.myproperty = $rootScope.myproperty;
});
For detail, you can have a look at the AngularJS Scope Hierarchies.
Hope that solve your problem.
In AngularJS, a Controller itself is an object defined by a Javascript constructor function and this constructor function is a callback to .controller method.
var myapp=angular.module('scopeExample', []);
myapp.controller('MyController',function MyController($scope){
$scope.name="john";
this.num=700;
});
In the above example, MyController is the constructor function which creates the Controller object with one property (num). I have three queries upon that:
Actually, what is the use of the Controller object in that case?
Does it have some more properties not visible and is it accessible from outside Angular?
How it is interconnected to its scope which in turn is another object?
I came upon the following queries because of the controller as syntax which creates a controller object that is a property of controller's scope and therefore easily accessible, e.g.
<div ng-app="scopeExample" ng-controller="MyController as ctrl">
<input id="box" ng-model="ctrl.num"> equals {{ ctrl.num }}
</div>
<script>
angular.module('scopeExample', [])
.controller('MyController', [function () {
this.num=12;
}]);
</script>
var x=angular.element('#box').scope().ctrl; //x is the controller object itself
1.a. What is the use of the Controller object in that case?
There is nothing special about this example, angular is an MVC framework(or any other buzz word you wish to use that describes almost the same thing), the controller's responsibility is to response to view events, update the model accordingly and execute business logic tasks (you can choose where to actually implement the logic, wheres in the controller itself or use services).
Of course that in this example the controller is pretty useless, because you have no logic, and only 2 proprieties.
1.b. Specking of ctrl-as syntax, in your example you injected 'scope' into the controller and added property ($scope.name), when you're using controller as it is recommended for you to avoid using scope unless you are obligated to do so. (e.g. $watch, parent...)
2.a. Does it have some more properties not visible?
No it doesn't have any invisible properties, you can check it easily by your self with the following code:
.controller('MyController', function () {
window.DoesThisControllerHaveInvisibleProps = this;
});
2.b. is it accessible from outside Angular?
I'm not sure that I fully understood what you've meant with "outside Angular", if so here is an example that the controller obj can be accessible from "outside":
class MyController {
static foo() {
console.log('hello!');
}
}
myapp.controller('MyController', MyController);
// maybe somewhere else in that module
MyController.foo();
3.How it is interconnected to its scope which in turn is another object?
As you said, when using controller as syntax angular is initializing the controller and put it on the $scope so it will be accessible in the template.
$scope is just an unnecessary glow and you should avoid using it. my way of seeing it is like it was angular implantation details, when migrating to ng-2 you will see that there is no more scope.
If you're interested in more detailed info about how exactly $scope and controllers in angular are working I suggest you have a look at
I'm wondering where and if there's a documentation on what can be injected into a function with dependency injection.
I understand that all registered services/factories in angularjs can be injected but when stumbling upon a solution to a problem I had, I read about the following:
function AppController($scope, $element, $compile) {
// ...
}
So from the tutorials I know $scope (but I did not find anything about $scope or scope in http://docs.angularjs.org/api/ - all I found was $rootScope).
Same with the $element. But $compile is a service just like $http - I understand where they come from.
Obviously I'm missing a very basic point about dependency injection and would be happy if someone could explain it to me.
$rootScope is an instance of $scope, and $scope docs are found here: http://docs.angularjs.org/api/ng.$rootScope.Scope
$element is implicitly injected into compile, controller and linking directive functions and is explained here: http://docs.angularjs.org/api/ng.$compile
While $rootScope can be explicitly injected anywhere you want, $element is available only inside the directives.
In the documentation for angularJS injector, some of the code uses $injector, while some code uses just injector. I am confused. What are the differences between these two, and where are the appropriate places to use them? I also have the same question for $scope and scope.
When you want to use injector, scope, or any other build in angularjs provider as dependency of other service you need to prefix them with $, as angular by convention registers all build in providers with $ prefix, so scope is registered as $scope, injector as $injector etc.
When angular instantiates objects(using injector btw) it checks what dependencies object has (as it needs to inject them) and the way it's done is by checking variables names of constructor function of that object, so that's why it's so important to name variables correctly or you'll get error unknown provider ...
When you retrieve injector as following:
var injector = angular.injector(['gaad', 'components']);
you don't use $ prefix, as it's normal variable and actually you can call it whatever you want ($injector included).
When you want to have injector as dependency, you need to name it as following:
angular.module('app').factory('$exceptionHandler', function($injector) {
...
});
or (convention needed when you use minification of angularjs scripts):
angular.module('app').factory('$exceptionHandler', ['$injector', function(anyNameYouWant) {
...
}]);
Similar for scope, when used in link function in directive:
link: function(scope, element, attr) {
}
you don't have to call it $scope as nothing is injected here. It's only one of function parameters. You can call it whatever you want, but convention here is to use scope not $scope to differentiate cases when scope is injected and when is used as parameter.