Reputation: 32240
In the AngularJS guide it says:
As the name suggests, the isolate scope of the directive isolates everything except models that you've explicitly added to the scope: {} hash object. This is helpful when building reusable components because it prevents a component from changing your model state except for the models that you explicitly pass in.
...which sounds great. It seems like the best practice would be to try to use an isolate scope in all your directives to keep them encapsulated.
However, I've found that if I try to add two directives with an isolate scope to the same element, Angular errors saying I can only have 1 directive with an isolate scope per element. That seems extremely limiting, and sort of defeats the purpose of an isolate scope.
To me, you shouldn't have to worry about whether or not your directive will be used with other directives when deciding whether or not your scope is isolated.
Am I missing something?
Should I be defaulting to non-isolate scopes? If so, is there a rule of thumb when I should be isolating my scope?
Upvotes: 1
Views: 70
Reputation: 6553
I think you can get around this by putting them on separate elements.
<div my-custom-dir1 with-some-property="1"><span my-custom-dir2 with-some-property="2"></span></div>
Upvotes: 0
Reputation: 37691
Generally, isolate scopes should be used on stand-alone directive - those directives that can't (and shouldn't) be modified by anything but themselves, no external influences, no add-ons (this includes modifying them by using another directive on their element, of course).
Why is this an issue?
Say you have two directives with isolate scope on your element. Each of them has a property called cdmckay
:
<directive1 directive2 ng-show="cdmckay"></directive1>
Which one would have a higher priority, the one from directive1
or the one from directive2
? Should the element be shown or not?
There's no way to know whether the used value will be from the directive one or the directive two. I guess it could be possible to combine multiple isolate scopes into a single one if they don't share property names (and only throw errors if they do), but I doubt Angular will ever take that path.
The way around this, in case your directives don't complement each other, is to use parent-child elements, so instead, say:
<directive1 directive2></directive1>
you do this:
<directive1>
<directive2></directive2>
</directive2>
I know it just doesn't seem right in many cases, but if you use isolate scope, this is one of the ways to combine directives. But again, if you expect directive1
to be extended with something, then build it that way (one of the ways would be to avoid using the isolate scope on directive2
then).
If you post your example, people will probably be able to give less generic answers. I hope this will get you moving in the right direction.
Brett's double-widget comment is spot-on:
If I have a calendar widget and a listview widget (that are implemented as directives with isolated scope), why on earth would I apply them to the same element?
Upvotes: 3