The directive with transclude: true causes the directive to create a new (transclosed) child region. This new prototype region is inherited from the parent region. In your case, the parent area is the area associated with the editCtrl controller.
Using two-way data binding in a child region (i.e. ng-model) to bind to a property of the parent region containing a primitive value (e.g. name ) always causes problems - well, I have to say that this does not work properly. When a region property changes in a child element (for example, you type in a second text box), the child element creates a new scope property that hides / shadow the property of the parent region with the same name. If the parent property contains a primitive value, that value is (essentially) copied to the child property when the child property is created. Future changes to the content area (for example, in the second text box) will only affect the child property.
Before entering into the second text field (i.e. before changing the property in the child), the child / transcluded area finds the name property in the parent area through prototype inheritance (the dashed line in the figure below). This is why the two text fields initially remain in sync. Below, if you type “Mark” in the first text box, it looks like this:

I created a fiddle where you can explore two areas. Click the "show area" link next to the second text box before entering text into the second text box. This allows you to see the transclosed coverage of the child. You will notice that at the moment it does not have a name property. Clean the console, enter in the second text box and click the link again. You will notice that the child region now has the name property, and the initial value is the value that the parent property ("Mark") has. If you entered “like Angular” in the second text box, it looks like this:

There are two solutions:
- do what @ pgreen2 offers (this is a "best practice" solution) - use an object instead of a primitive. When an object is used, the child / transcluded scope does not receive a new property. Only prototype inheritance is used here. In the figure below, suppose that the editCtrl $ area has this object:
$scope.myObject = { name: "Mark", anotherProp: ... } :

- use the $ parent child in the content area (this is a fragile solution and is not recommended because it makes assumptions about the HTML structure): use
ng-model="$parent.name" inside the <input>, which is inside the <tabs> element. The first image above shows how this works.
A syntax error occurs when using scope: {name: '='} , because when using two-way data binding (that is, when using '=') interpolation is not allowed, i.e. {{}} cannot be used. Instead of <tabs name="{{name}}"> use <tabs name="name"> .
Using '@' works the same as for the transclude case, since ng-transclude uses the transcluded scope, not the selection area that is created using scope: { ... } .
For (lots) more information about areas (including pictures), see What are the nuances of the volume of the prototype / prototype inheritance in AngularJS?
Mark Rajcok Jan 23 '13 at 16:46 2013-01-23 16:46
source share