Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't multiple directives ask for an isolated scope on the same element?

If Angularjs - Multiple directives on element with one being isolate scope is right, the isolated scope is bound to the directive, so why would there be any clashes? The documentation for this error states that processing them would result in a collision or an unsupported configuration. I don't buy this. Multiple directives already share the element's scope, which is surely where clashes/unsupported configurations would come in. I've tried looking for the "why" on this, but have come up empty handed.

Can someone explain / give an example where this would indeed create a collision or an unsupported configuration?

like image 317
Dororo Avatar asked Dec 15 '14 14:12

Dororo


2 Answers

Why can't multiple directives on the same element get separate isolated scopes

The answer is simple - there needs to be only one scope to bind the child elements to (see source), because assignments to scope properties done in descendant elements need to have a clear target. The rest is a question of wording.

While it is appropriate, in a way, to refer to the isolate scope being created "for that particular directive" (as the linked answer does), it is only in the sense that the directive that requested the isolation is the only one of the directives on that element to have access to the isolated scope. So, the scope is created to isolate the directive and the child elements from the rest of that "level" of DOM.

Why can't multiple directives get the same isolated scope

Giving multiple directives the same isolated scope would risk a clash of scope binding configurations (multiple directives could try to bind to the same property on the isolated scope).

Why can't directives with lower priority use the isolated scope

A simple and compelling argument is that the {{interpolated.expressions}} on an element need to be evaluated against the same scope as plain expressions (supplied to directives that support them), otherwise the whole thing would be a total mess. (Interpolation of {{expressions}} is done separately, so a directive accepting a plain expression in one attribute and String in another could be configured with expressions evaluated against different scopes.)

If they really need to, they can access the isolated scope (but this needs Debug Data to be enabled). If they have lower priority than the directive creating the isolate scope, they can just use element.isolateScope() in their linking function (see demo).

like image 69
hon2a Avatar answered Oct 20 '22 11:10

hon2a


This is likely because scopes are associated at an element level (AFAIK). Thus, at a given element, there is only one scope associated with it, which can be one of Parent, Child or Isolated. The Scope documentation on the AngularJS Guide also references this (https://docs.angularjs.org/guide/scope)

No element can have more than one scope associated with it (by design), because scopes represent the application structure as well as the context for any given element.

Because of this, when two directives on the same element ask for an isolated scope, AngularJS recognizes it would have to create two different scopes catering to the exact same element, which is not a supported behavior. The only way would then be to somehow merge the two scopes to allow for its basic assumption, which can cause collisions if the two isolated scopes both ask for binding to the same scope variable like

   scope: { myData: '=' }

Now if both directives ask for this, or add certain functions to the scope, then you are into uncharted territory depending on which directive executes first.

like image 33
Shyam Seshadri Avatar answered Oct 20 '22 09:10

Shyam Seshadri