2

I'm trying to keep my watches down by using one-time binding (::) in most places.

However, I've run into the situation where I need to wait for one property of an object to arrive from our server.

Is there someway I can make Angular bind twice (first to a placeholder and second to the actual value)?

I tried accomplishing this using bindonce but it did not seem to work (I am guessing this is because bindonce wants to watch an entire object, not a single property).

Another solution would be if I could somehow remove a watch from the templates after the value comes in, if that is possible.

My objects look something like this:

{
 name: 'Name',
 id: 'Placeholder'
}

And my template:

<div ng-repeat="object in objects">
 {{::object.name}}
 {{::object.id}}
</div>

Id will change once and only once in the application life time, having a watch forever for a value that will only change once feels wasteful as we'll have many of these objects in the list.

2
  • 1
    Initialize the id with null or undefined, instead of initializing it with 'Placeholder'. Commented May 22, 2015 at 6:37
  • Yes, I tried this (and it works) but was told that it's not acceptable to not display anything while we wait for the value to arrive (the wait time may vary, between a few ms and a few s). Commented May 22, 2015 at 6:46

1 Answer 1

1

I think this is what you are looking for! Plunkr

I just wrote a bind-twice directive and if I did not completely missed the question it should solve your problem:

directive("bindTwice", function($interpolate) {
    return {
      restrict: "A",
      scope: false,
      link: function(scope, iElement, iAttrs) {
        var changeCount = 0;

        var cancelFn = scope.$watch(iAttrs.bindTwice, function(value) {
          iElement.text(value === undefined ? '' : value);
          changeCount++;
          if (changeCount === 3) {
            cancelFn();
          }
        });
      }
    }
  });

What I do is, I add a watcher on the scope element we need to watch and update the content just like ng-bind does. But when changeCount hit the limit I simply cancel $watch effectively cleaning it from watchlist.

Usage:

  <body ng-controller="c1">
    <div ng-repeat="t in test">
      <p>{{ ::t.binding }}</p>
      <p bind-twice="t.binding"></p>
      <p>{{ t.binding }}</p>  
    </div>
  </body>

Please see Plunkr for working example.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.