javascriptangularjsone-time-binding

Angular One-time bind conditionally OR unbind listener when a specific value is set


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?


Solution

  • 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