Reputation: 4288
I can't seem to get one-time binding to work. My actual application logic is a bit too complex for plunker but I can't even get a simple scenario like this http://plnkr.co/edit/ka57xquoR2ZdY2F0li76 to work in my app. Here is the plunker of my exact code down to file structure. I removed all the substance out of the app to get the simplest one-time binding example to work - it works in the plunker but not in my code.
I am using AngularJS 1.3.0-rc.4
Here is a snippet of what's in the plunker
{{::current.text}}
<br />
{{current.text}}
<br />
<input ng-model="current.text" type="text" />
<br />
In my app both {{::current.text}}
and {{current.text}}
updated when the text box is updated...
Is there something that could be turning off or one-time binding or preventing the scope variables from settling so the onetime binding can kick in?
Upvotes: 3
Views: 1777
Reputation: 6693
A slightly different case I encountered is where the expression returns a result that is in some way tied to the current time in milliseconds, so sufficiently granular as to return a different result on each of possibly multiple invocations within a digest loop.
In my case, although the one-time bound expression will have been marked for deregistration at the end of the current digest cycle, the expression was being re-evaluated multiple times within the same digest cycle as far as I could gather. This was causing the digest iteration limit to be exceeded and result in console log error messages being spewed out like the following:
Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations:
[[{"msg":"fn: oneTimeWatch","newVal":"1475668099352","oldVal":"1475668099346"}],
[{"msg":"fn: oneTimeWatch","newVal":"1475668099356","oldVal":"1475668099352"}],
[{"msg":"fn: ...
In my particular case, guaranteeing that the expression always returned the same value for a given input after first invocation for that input allowed the one-time binding to work correctly. A bit counter-intuitive, which is why it caught me out, but perhaps this is useful to somebody!
Upvotes: 0
Reputation: 4288
Turned out it was Batarang (chrome's angularjs debugging extension) that was causing this behavior. My guess it that it's constant monitoring prevents the scope variable from settling and hence the one-time binding wasn't kicking in.
Upvotes: 21
Reputation: 19193
As pointed out by Richard Hermanson, you'll have to remove all html that is not related to that bug until you have a subset simple enough to understand what's causing it.
If you want a random guess, maybe the once-bound element is contained by an element that is itself rebuilt in the DOM, hence the bind-once is reinitialized each time.
For instance
<div ng-if="someOndition">
<div>{{::current.text}}</div>
</div>
Each time the ng-if goes from false to true, its inner html is recompiled and added to the DOM. That may not be precisely your issue, but the only thing I could see is recompiling the directive.
Upvotes: 2