Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>OK, I'm going to take a crack at this one... It seems you're changing both the isolated child AND parent variables before a <code>$digest</code> cycle where the bi-direction logic syncs the two. Here's the details:</p> <ol> <li>First your <code>lock()</code> function is executed by clicking on the button. This updates the isolated <code>$scope.key</code> variable. <strong>NOTE: This does NOT <em>immediately</em> update the parent <code>$scope.pKey</code>; that would normally happen at the next <code>$digest</code> cycle but does not in this case. Read on...</strong></li> <li>Within <code>lock()</code> you are calling <code>parentUpdate()</code> which updates the parent's <code>$scope.pKey</code> variable.</li> <li>THEN the <code>$digest</code> cycle executes. When it loops it's way to the parent scope a change to <code>$scope.pKey</code> is correctly detected.</li> <li>The change to <code>$scope.pKey</code> triggers a <code>watch()</code> that was created by the bi-directional binding in the isolated scope. <a href="https://github.com/angular/angular.js/blob/63c5334c84b7269428c710226764d1f08a36e0d4/src/ng/compile.js#L1035-L1048" rel="nofollow noreferrer">These lines</a> are the critical ones..</li> <li>The <code>watch()</code> created by the isolated scope checks whether it's value for the bi-directional binding is in sync with the parent's value. If it isn't (and it's not in this scenario) the parent's value is copied to the isolated scope <strong>even though the isolated scope's value has changed also and in fact was changed first</strong>.</li> </ol> <p><a href="https://stackoverflow.com/questions/9682092/databinding-in-angularjs">Misko's famous post on Angular data-binding</a> describes the benefits of the <code>$digest</code> cycle approach. What you're seeing here is a conscious side-effect of the <code>$digest</code>'s approach to change coalesence wherein, as the source code comment says, <a href="https://github.com/angular/angular.js/blob/63c5334c84b7269428c710226764d1f08a36e0d4/src/ng/compile.js#L1041" rel="nofollow noreferrer"><code>parent changed and it has precedence</code></a>... and that means your isolated scope's change loses.</p> <p>The <code>$timeout()</code> approach you noted above avoids this issue by changing only the isolated scope's value in the first <code>$digest</code> cycle which allows it to be copied to the parent scope successfully and THEN calling <code>parentUpdate()</code></p> <p>The <a href="http://docs.angularjs.org/api/ng.$compile" rel="nofollow noreferrer"><code>$compile</code> documentation</a> says: </p> <blockquote> <p>Often it's desirable to pass data from the isolated scope via an expression and to the parent scope, this can be done by passing a map of local variable names and values into the expression wrapper fn. For example, if the expression is increment(amount) then we can specify the amount value by calling the localFn as localFn({amount: 22}).</p> </blockquote> <p>This means, at step #2 you could pass in your value for <code>pkey</code> via an object map like this:</p> <pre><code>parentUpdate({pkey: 'D+' + $scope.key }) </code></pre> <p>Here's the updated fiddle: <a href="http://jsfiddle.net/KbYcr/" rel="nofollow noreferrer">http://jsfiddle.net/KbYcr/</a></p>
 

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