I have a directive with an isolate-scope (so that I can reuse the directive in other places), and when I use this directive with an ng-repeat
, it fails to work.
I have read all the documentation and Stack Overflow answers on this topic and understand the issues. I believe I have avoided all the usual gotchas.
So I understand that my code fails because of the scope created by the ng-repeat
directive. My own directive creates an isolate-scope and does a two-way data-binding to an object in the parent scope. My directive will assign a new object-value to this bound variable and this works perfectly when my directive is used without ng-repeat
(the parent variable is updated correctly). However, with ng-repeat
, the assignment creates a new variable in the ng-repeat
scope and the parent variable does not see the change. All this is as expected based on what I have read.
I have also read that when there are multiple directives on a given element, only one scope is created. And that a priority
can be set in each directive to define the order in which the directives are applied; the directives are sorted by priority and then their compile functions are called (search for the word priority at http://docs.angularjs.org/guide/directive).
So I was hoping I could use priority to make sure that my directive runs first and ends up creating an isolate-scope, and when ng-repeat
runs, it re-uses the isolate-scope instead of creating a scope that prototypically inherits from the parent scope. The ng-repeat
documentation states that that directive runs at priority level 1000
. It is not clear whether 1
is a higher priority level or a lower priority level. When I used priority level 1
in my directive, it did not make a difference, so I tried 2000
. But that makes things worse: my two-way bindings become undefined
and my directive does not display anything.
I have created a fiddle to show my issue. I have commented out the priority
setting in my directive. I have a list of name objects and a directive called name-row
that shows the first and last name fields in the name object. When a displayed name is clicked, I want it to set a selected
variable in the main scope. The array of names, the selected
variable are passed to the name-row
directive using two-way data-binding.
I know how to get this to work by calling functions in the main scope. I also know that if selected
is inside another object, and I bind to the outer object, things would work. But I am not interested in those solutions at the moment.
Instead, the questions I have are:
- How do I prevent
ng-repeat
from creating a scope that prototypically inherits from the parent scope, and instead have it use my directive's isolate-scope? - Why is priority level
2000
in my directive not working? - Using Batarang, is it possible to know what type of scope is in use?
scope: true
for your directive. See also (if you haven't already) stackoverflow.com/questions/14914213/… Also, just because a directive will be used in multiple places does not mean we should automatically use an isolate scope. – Mark Rajcokng-repeat
. I think it is valuable to be able to mix standalone directives withng-repeat
. To be continued... – Deepak Nulung-repeat
should not have a scope.ng-repeat
having a scope does make sense for the typical use-case, so I am not suggesting it be changed. Instead, like I commented in Alex Osborn's answer, I think I will create a repeat directive based onng-repeat
that does not create its own scope. This can then be used for repeating directives which have their own isolate-scopes. To be continued... – Deepak Nulung-repeat
or the custom scope-less repeat directive. I think it is okay for the "caller" to know this, but it is not okay for a "callee" (the directive being repeated) to know whether it is being repeated or not. To be continued... – Deepak Nulu