jbmilgrom
jbmilgrom

Reputation: 23251

When to use AngularJS's one time binding (i.e. `<`) introduced in 1.5?

Given

<my-component my-attr="parentModel">

and a directive definition that includes:

scope: { localModel:'<myAttr' }

angular will set up a one time binding. What this means is that

The expression is evaluated in the context of the parent scope

and

the isolated scope property localModel will reflect the value of parentModel on the parent scope. Any changes to parentModel will be reflected in localModel, but changes in localModel will not reflect in parentModel

This is great, but how is anything accomplished above what is already accomplishable with an angular expression using ampersand notation (i.e. &)?

Given

<my-component my-attr="parentModel">

and a directive definition that includes:

scope: { getModel:'&myAttr' }

any calls to scope.getModel() should also evaluate the "parentModel" expression in the context of the parent scope and provide such value to the isolated scope of the directive, and here there is no need to$watch the parentModel or to worry about values in the isolate scope propagating back up to the parent.

Upvotes: 0

Views: 273

Answers (1)

Malk
Malk

Reputation: 11983

I made this code snippet to try to understand the question better. It seems like there are obvious differences between the two options such as how the link function is handled and some auto $watch()ing. But I'd never used an expression in this way and I think I'm missing something.

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

app.controller('MainCtrl', function() {
  this.v1 = 1;
  this.v2 = 2;
  this.v3 = 3;
});

app.directive('myComponentOne',
  function() {
    return {
      restrict: 'E',
      scope: { v: "<val" },
      template: '<input ng-model="v"/>',
      link: s => s.v = 99
    };
  });

app.directive('myComponentTwo',
  function() {
    return {
      restrict: 'E',
      scope: { v: '&val' },
      template: '<input ng-model="v"/>',
      link: s => s.v = 99
    };
  });

app.directive('myComponentThree',
  function() {
    return {
      restrict: 'E',
      scope: { v: '=val' },
      template: '<input ng-model="v"/>',
      link: s => s.v = 99
    };
  });
<div ng-app="app">
  <div ng-controller="MainCtrl as main">
    <div>
      One-way binding:<br>
      parentScope=<input ng-model="main.v1" /><br>
      localScope=<my-component-one val="main.v1"></my-component-one>
    </div>
    <hr>
    <div>
      Expression:<br>
      parentScope=<input ng-model="main.v2" /><br>
      localScope=<my-component-two val="main.v2"></my-component-two>
    </div>
    <hr>
    <div>
      Two-way binding:<br>
      parentScope=<input ng-model="main.v3" /><br>
      localScope=<my-component-three val="main.v3"></my-component-three>
    </div>
  </div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.1/angular.min.js"></script>

Upvotes: 1

Related Questions