Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Okay, through a lot of the comments above, I have discovered the confusion. First, a couple of points of clarification:</p> <ul> <li>ngRepeat does not affect your chosen isolate scope</li> <li>the parameters passed into ngRepeat for use on your directive's attributes <em>do</em> use a prototypically-inherited scope</li> <li>the reason your directive doesn't work has nothing to do with the isolate scope</li> </ul> <p>Here's an example of the same code but with the directive removed:</p> <pre class="lang-html prettyprint-override"><code>&lt;li ng-repeat="name in names" ng-class="{ active: $index == selected }" ng-click="selected = $index"&gt; {{$index}}: {{name.first}} {{name.last}} &lt;/li&gt; </code></pre> <p>Here is a <a href="http://jsfiddle.net/BWybB/10/" rel="noreferrer">JSFiddle</a> demonstrating that it won't work. You get the exact same results as in your directive.</p> <p>Why doesn't it work? Because scopes in AngularJS use prototypical inheritance. The value <code>selected</code> on your parent scope is a <strong>primitive</strong>. In JavaScript, this means that it will be overwritten when a child sets the same value. There is a golden rule in AngularJS scopes: model values should <em>always</em> have a <code>.</code> in them. That is, they should never be primitives. See <a href="https://stackoverflow.com/a/14049482/259038">this SO answer</a> for more information.</p> <hr> <p>Here is a picture of what the scopes initially look like.</p> <p><img src="https://i.stack.imgur.com/5abQ5.png" alt="enter image description here"></p> <p>After clicking the first item, the scopes now look like this:</p> <p><img src="https://i.stack.imgur.com/mNipO.png" alt="enter image description here"></p> <p>Notice that a new <code>selected</code> property was created on the ngRepeat scope. The controller scope 003 was not altered.</p> <p>You can probably guess what happens when we click on the second item:</p> <p><img src="https://i.stack.imgur.com/1wyAf.png" alt="enter image description here"></p> <hr> <p>So your issue is actually not caused by ngRepeat at all - it's caused by breaking a golden rule in AngularJS. The way to fix it is to simply use an object property:</p> <pre class="lang-js prettyprint-override"><code>$scope.state = { selected: undefined }; </code></pre> <pre class="lang-html prettyprint-override"><code>&lt;li ng-repeat="name in names" ng-class="{ active: $index == state.selected }" ng-click="state.selected = $index"&gt; {{$index}}: {{name.first}} {{name.last}} &lt;/li&gt; </code></pre> <p>Here is a <a href="http://jsfiddle.net/BWybB/9/" rel="noreferrer">second JSFiddle</a> showing this works too. </p> <p>Here is what the scopes look like initially:</p> <p><img src="https://i.stack.imgur.com/xww7Z.png" alt="enter image description here"></p> <p>After clicking the first item:</p> <p><img src="https://i.stack.imgur.com/POpOL.png" alt="enter image description here"></p> <p>Here, the controller scope is being affected, as desired.</p> <p>Also, to prove that this will still work with your directive with an isolate scope (because, again, this has nothing to do with your problem), here is a <a href="http://jsfiddle.net/BWybB/38/" rel="noreferrer">JSFiddle</a> for that too, the view must reflect the object. You'll note that the only necessary change was to use an <em>object</em> instead of a <em>primitive</em>.</p> <p>Scopes initially:</p> <p><img src="https://i.stack.imgur.com/cjaw5.png" alt="enter image description here"></p> <p>Scopes after clicking on the first item:</p> <h2><img src="https://i.stack.imgur.com/bSTOk.png" alt="enter image description here"></h2> <p>To conclude: once again, your issue isn't with the isolate scope and it isn't with how ngRepeat works. Your problem is that you're breaking a rule that is known to lead to this very problem. Models in AngularJS should always have a <code>.</code>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. COMy experiments with directives with isolate-scopes and 2-way data binding lead me to believe that the `.` golden rule is only required for scopes that have prototypical inheritance. With isolate-scopes, the variables you are interested in are defined in the `scope: {}` definition in the directive, and therefore those variables will exist in the isolate-scope from the beginning. Also, they don't mask the parent variables because the isolate-scope does not prototypically inherit from the parent scope. i.e. there is no "parent" scope to mask.
      singulars
    2. COBut updating a two-way bound variable in the isolate-scope (defined with `=` in `scope: {}`) causes the corresponding variable in the outer scope to change because of the two-way data binding. I can't remember trying this out with primitive variables in the isolate-scope, but I have definitely seen this working with object/reference variables. Note that I am talking about assigning a new object value to the variable, not modifying a property inside the object. i.e. I am not following the `.` golden rule in my directive and it still works.
      singulars
    3. COI have forked my fiddle and replaced the `ng-repeat` with a manual repetition: http://jsfiddle.net/jtjk4/1/ (I created variables for each index in `MainController` because my directive uses an `inIndex : '='` binding for the index). You will see that this works fine. My directive assigns a new value to `ioSelected` without using `.` and it works correctly (the outer scope sees the change and displays the selected name in the HTML output). This is what leads me to say that it is `ng-repeat` (specifically its scope) that breaks my two-way data-bound isolate-scope directive. What am I missing?
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload