javascriptangularjsangularjs-bindings

AngularJS – Subtract two-way bind from one-time bind


In my Angular 1.4.8 app I want to calculate the difference between an original value and the value after it has been changed by the user.

<table>
  <tr>
    <td>Value</td>
    <td>Difference</td>
  </tr>
<tr ng-repeat="value in values">
  <td>{{ value }}</td>
  <td>{{ ::value - value }}</td>
<tr>
</table>

The values are an array, for example $scope.values = [1,5,8,3];.

But this doesn't work. Angular does the subtraction first and then binds the difference field forever at zero. Or if I do this, it just crashes:

<td>{{ (::value) - value }}</td>

Solution

  • The one-time binding operator isn't associative, it applies to the whole watch expression. What you can do is set a variable one-time and use that.

    <tr ng-repeat="value in values">
      <td>{{:: originalValue = value }}</td>
      <td>{{originalValue - value }}</td>
    <tr>
    

    In this example the first watcher will compute originalValue until it stabilizes at which point the watcher will be de-registered, freezing both the DOM and the value of originalValue. The second watcher will continue computing its expression with the frozen value.