2

I've something like below in DOM:

 <div ng-if="variant"
    ng-include="'size-picker.html'">
 </div>

And in controller:

$scope.variant = false;
// after some unknown time there may be:
$scope.variant = true;

I wanted to show that div when variant is true. So,

$scope.variant will start by false. After some time it may/may not become true. When $scope.variant became true it's never gonna change it's value. So what I want is one-time bind that ng-if once $scope.variant is true.

An approach like:

<div ng-if="::variant"
    ng-include="'size-picker.html'">
</div>

will stop binding when it's false.

I can achieve it by stop assigning false to variant in the first time, but it's not possible in my case.

How can I unbind the ng-if when variant is true?

2 Answers 2

2

You can use $watch, to unregister a binding or a scope

$watch returns a deregistration function.

You can unregister a $watch with the function returned by the $watch call:

var unwatch = $scope.$watch('variant', function(newValue, oldValue) {
    if(newValue == true)
    {
        unwatch();
    }
});

So, once your variant becomes true, the watch on it is removed, and the binding gets stopped.

var app = angular.module( "Demo", [] );

app.controller(
  "AppController",
  function( $scope ) {
    $scope.count = 0;
    $scope.after_unwatch = false;

    var unbindWatcher = $scope.$watch(
      "count",
      function( count ) {
        alert( "Watching click count." );
        if ( count >= 5 ) {
          $scope.after_unwatch = true;
          unbindWatcher();
        }

      }
    );


  
    $scope.incrementCount = function() {
      $scope.count++;
    };

  }
);
<html>
<body>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
  <div  ng-app="Demo" ng-controller="AppController">
    <h1>
      Unbinding $watch() Listeners In AngularJS
    </h1>

    <p>
      <a ng-click="incrementCount()">Click it for five times, and after that watch on `count` is removed.</a>
      &raquo;

    </p>

    <p ng-show="after_unwatch">
      <em>The watch on click is removed.</a>
    </p>
  </div>
 </body>
</html> 

Run this code

Here is a plunker

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

4 Comments

Thanks. So you are saying angular will stop watching on that variable completely? even it's dependent on other places like DOM?
yes, once you put that scope variable in $watch function, its scoped is removed based on a condition.
let me give you an example, posting it.
No. I switched tasks now. Thinks it will work okay for me. Thanks @Sravan
2

The docs say:

One-time expressions will stop recalculating once they are stable, which happens after the first digest if the expression result is a non-undefined value.

So you could start with an undefined value.

3 Comments

In my case, It will start with false. It's a huge codebase. I have limits to do that.
In case Sravan's answer doesn't work for your specific case, you could use a different undefined variable for the ngIf, and then monitor variant's state, updating that variable appropriately. Not optimal, but with difficult constraints sometimes that's the best we can manage
That's a nice way doing that.

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.