I was trying to understand scope in angularjs.
Say while registering a directive in angularjs if we dont provide any scope as the property of the object, what is the scope of the object then?
For example consider the following code:-
app.directive("kid", function() {
return {
restrict: "E",
template: '<input type="text" ng-model="chore"> {{chore}}'
};
});
Now say if i have 2 elements in my html:-
<kid></kid>
<kid></kid>
So how do above end up sharing the same scope? I am not able to find convincing answer yet.
Yes, As you didn't declared any scope option of directive, it will share the same scope.
Here is Demo Plunkr
Now come to the point, what is scope object?
scope object in Angular is nothing having context information and that will available on html, can also be utilized to provide two way binding. Basically scope is binded with some controller.
When things comes to directive scope, if you didn't mention scope property inside directive, that means directive shares the scope of the controller where the directive element has been placed.
To make them treated as a different scope for each directive you could create an an directive with an isolated scope, which can be defined using scope: {} inside a directive, when you define a scope: {} inside a directive, it creates an isolated child scope which is not prototypically inherited from the parent scope using $scope.$new(true) method.
Plunkr with isolated scope
Your question is about scope inheritance and isolate scope.
If you do declare a scope property on a directive object then the directive has its own isolate scope.
If you don't declare a scope property on your directive object the directive inherits the scope of the scope it was instantiated in.
So with your definition of the kid directive that doesn't declare an isolate scope the kid directives in the code example below both inherit the scope of the controller that they are instantiated in.
<div ng-controller="myCtrl">
<kid></kid>
<kid></kid>
</div>
Scope is an object that refers to the application model. It is an execution context for expressions. Scopes are arranged in hierarchical structure which mimic the DOM structure of the application. Scopes can watch expressions and propagate events.
Scope characteristics
Scopes provide APIs ($watch) toenter image description here observe model mutations.
Scopes provide APIs ($apply) to propagate any model changes through
the system into the view from outside of the “Angular realm”
(controllers, services, Angular event handlers).
Scopes provide context against which expressions are evaluated.
For example {{username}} expression is meaningless, unless it is evaluated against a specific scope which defines the username property.Scope is the glue between application controller and the view.
Related
I have create a custom directive that displays the directive template within the current view:
<div class="upper-outfits-layer" ng-show="outfitExpanded">
<expanded-outfit outfit="outfits[currentOutfit]"></expanded-outfit>
</div>
That will display an html template. The view this directive is placed within, has its own controller. I need to access the views scope variables from this directive and vice versa.
Is it possible to access a sperate controller from a custom directive?
Do not use isolated scope in your directive. You can directly get access your view scope.
(In case of Isolated scope) Pass the variables in the attribute of your directive. They will be accessible to your directive through your isolated scope.
(In case of Isolated scope) Use scope.$parent in your directive to access view scope.
If you don't isolate the directive's scope using scope:{}, you should be able to access parent controller's variables. Maybe add the directive code to your question if the problem persists...
While implementing directive I came across isolate scope , I am having Confusion why we have to Use isolate scope instead of scope.
When using an isolated scope, the directive's scope does not prototypically inherit from its parent. The directive has no access to the parent scope. This gives you the highest encapsulation. You should use an isolated scope, whenever you're designing reusable components.
Directives have access to the parent scope by default. For example, the following directive relies on the parent scope to write out a user object’s name:
angular.module('myDirective').directive('sharedScope', function () {
return {
template: 'Name: {{user.name}}'
};
});
The problem with this code is that you need to have an information about the parent scope, thus if the parent scope changes? The directive will become not usable anymore. That's when isolated scope comes in handy. Therefore isolated scope is used whenever directive is designed to be reusable. These are some good blog post which explain in depth the topic
AngularJS Directives, Using Isolated Scope with Attributes
Angularjs Sticky Notes
Creating Custom AngularJS
directives
I have been working a while in angular directive, for now, I came out with a problem.
What is the different between module.controller and the controller that could be defined in directive?
angular.module().controller()
angular.module().directive(function(){
return {
controller:
}
});
The definition of both of them seems the same.
Another question is, would I assign the controller that defined by angular.module().controller() for directive controller?
Basically the functionality of both these controllers is essentially the same except that there is difference in the scope they act upon. Scope of the controller defined by the directive only applies to the element & children of that element, where the directive has been applied. Whereas controllers defined by the module act on scope of all elements where controller is defined with ng-controller.
Directive can also make use of the controller defined by angular.module(). This is achieved using controller key in the directive and providing the name of the module controller as a string.
Have a look at this example.
Module controllers are used to initialize scope on the hosting page. The scope on the hosting page relies on prototypical scope inheritance in a parent-child relationship.
Directive controllers are used to initialize scope for the directive's scope, which can be one of two types:
1. Isolated scope
2. Child scope (prototypical)
They are similar in that both kinds of controllers are used for initialization of scope. They are different in that each initialize their respective scopes: module controllers initialize page scope, directive controllers initialize the directive's scope.
The logic within a module controller is usually application specific but the logic within a directive controller is usually application-agnostic. Directive's are intended to be reusable, but application controllers are not.
I see so many examples https://docs.angularjs.org/guide/directive and What is the difference between & vs # and = in angularJS but even I don't understand the scope principe in a directive. It's very confusing to use this. Some examples make use of scope:true; and
scope: {
sourceObj: '=',
lookupSource: '#',
searchRes: '&',
disableSearch: ''
}
What is using a boolean value (scope:true;) doing exactly?
scope:true
If you set scope:true (instead of scope: { ... }) then prototypical inheritance will be used for that directive.
This is not something AngularJS is doing – this is how JavaScript prototypal inheritance works.
example
scope:false (default)
the directive does not create a new scope, so there is no inheritance here. This is easy, but also dangerous because, e.g., a directive might think it is creating a new property on the scope, when in fact it is clobbering an existing property. This is not a good choice for writing directives that are intended as reusable components.
example
scope: {......}
the directive creates a new isolate/isolated scope. It does not prototypically inherit. This is usually your best choice when creating reusable components, since the directive cannot accidentally read or modify the parent scope.
Notice, even the parent scope has a name “Harry”, the textbox inside directive is blank. This is because of the new Isolated scope doesn’t know anything about its parent scope.
example
Notice, even the parent scope has a name “Harry”, the textbox inside directive is blank. This is because of the new Isolated scope doesn’t know anything about its parent scope.
NOTE: I dont want now post diferences between scope properties (#,&,=) , it will be another lesson
from this source
It's all about whether or not you want to create an isolated (new) scope for your directive or you want to inherit the from the parent scope. Specifying scope: true is essentially the same as scope: {}. It just says, 'hey, I want my own private scope here'. The only difference between those two is that you can use the object notation to specify your own scope properties to use in your directive.
What does the scope parameter in the link property of the directive definition object represent. Is it the scope that the directive will be used in or is it an isolated scope for every time the directive is used?
If you do not define scope in your directive then it has access to your parent scope. If you define it as
scope: {}
Then an isolate scope is created.
Should be able to see more in the docs, but that is a basic rundown.
https://docs.angularjs.org/guide/directive