Join the Stack Overflow Community
Stack Overflow is a community of 6.7 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

Please check this plnkr

I have read everyhting can find about directives, scope and isolated scopes. But I still cannot understand the way to make this work.

The directive I created works perfectly as long as it is not nested within another directive.

When nested, the 'localFunc: "&func"' attributes bind to outer controller scope just fine but 'localAttr: "=attr"' scope fail.

I would be ever so grateful is anyone can help me understand why.

share|improve this question
up vote 31 down vote accepted

Pictorially, here is what your scopes look like before we type into either textbox: scopes

Notice that isolate scope 006's parent is the transcluded scope that is created by directive container. As such, the searchText in scope 006 will be databound to scope 005 (rather than scope 003) because a primitive is being used.

If we type 11 into the first textbox, and 22 into the second textbox and examine the scopes again, we can see where the databinding took place:

enter image description here

searchforThis2 is colored yellow in scope 005 to indicate that a new property was created. This happened because a primitive is used -- scope 005 does not use prototypal inheritance here, it just creates a new primitive property on itself (i.e., it does not look in scope 003 for the property name). The other yellow items indicate that the primitive values changed.

As you already discovered, the "best practice" solution to this problem is to bind to object properties (rather than primitives) in the parent scope (i.e., scope 003).

Using the following in your controller:

$scope.obj = {searchforThis1: "Sample Text 1", searchforThis2: "Sample Text 2"};

and in your HTML:

<search searchtext="obj.searchforThis1"...>
...
<div container>
  <search searchtext="obj.searchforThis2"...>

The scopes now look like the following: enter image description here

If we type 11 into the first textbox, and 22 into the second textbox and examine the scopes again, we can see where the databinding took place:

enter image description here

Because scope 006 is an isolate scope, it uses its $parent to get to scope 005 (like above). From there, however, prototypal inheritance is in play, since we are not using primitives. Object property searchforThis2 is located in scope 003.

share|improve this answer
    
Brilliant explanation. Thank you. Did you draw those diagrams just for this question or do you have some tool that can inspect angularjs scopes and prepare such diagrams? – thrag Mar 31 '13 at 2:59
2  
@thrag, I have a tool that I wrote/am writing. – Mark Rajcok Apr 3 '13 at 2:59
5  
@MarkRajcok Could you please consider releasing this tool in public, so we can dynamically draw these brilliant scope maps? I believe many headaches could be avoided and many long conversations would be saved :) – Thalis K. Mar 24 '14 at 15:46

Never fails. Hours of googling turns up nothing until I actually type the question then I get the combination of search keywords and voila! the answer appears.

Thanks to this very illuminating post I learned that my problem is so common the solution even has a name - "The dot rule".

Basically you need to refer to an inherited object on the controller rather than a property and the problem goes away.

share|improve this answer
3  
beneficial reading from angular github wiki github.com/angular/angular.js/wiki/… – charlietfl Mar 30 '13 at 15:16
1  
Thank you for referencing that 'very illuminating post'! – Airn5475 Oct 6 '14 at 20:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.