简体   繁体   中英

one-time binding with ng-if in angular?

If I have a view that does:

<div ng-repeat="foo in foos">
  <p ng-if="bar">omg lol</p>
  <p ng-if="!bar">lol omg</p>
</div>

I am actually creating (2 * foos.length) + 1 $$watchers, which is really not good. I have found several sources online that say you can do ng-if="::bar", but the number of watchers does not change when I do that. Is there a way to force ng-if to be a one time binding?

It is really, really dumb to have to do:

<div ng-repeat="foo in foos" ng-if="bar">
  <p>omg lol</p>
</div>
<div ng-repeat="foo in foos" ng-if="!bar">
  <p>lol omg</p>
</div>

Which I believe will give me something like 4 $$watchers instead... So I am looking for an alternative to avoid having to be silly like that.

Just extending my comments to answer.

Angular 1.3 one-time binding syntax ( :: ) indeed will remove unnecessary watches. Just that you need to measure the watches a while after you set the relevant data. Here is why it is. When you set a one-time bound property on the view, angular will set a temporary watch on it until it gets a defined value, ie anything but undefined . This approach is there for a reason - in order to support the bound values that are populated via a deferred operation like ajax call, timeout, promise chain resolution etc.. Without this :: will not work successfully on anything but pre-populated bound values.

So just make sure that you set some value at some point in time to the one-time bound values. Don't let it remain undefined.

Say when you have a condition <div ng-if="::lol"></div> repeated 100 times. Just make sure when you bind the value to the repeater or some operation that determines the status of lol even if that operation fails (say a ajax call error) still set a value (even null is also a value in javascript) to it. Watches will be removed after the upcoming digest cycle which renders the respective DOM bindings.

In your specific plunker you could as well do:

<ul ng-repeat="item in items"  ng-if="::lol">
  <li>{{ ::item }}</li>
</ul>

instead of

<ul ng-repeat="item in items">
  <li ng-if="::lol">{{ ::item }}</li>
</ul>

您需要使用Bindeonce来执行此操作: https//github.com/Pasvaz/bindonce

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM