3

I have tried googling this long time but could not find valid answer. Why there is no one time binding in angular 2. I dont think ChangeDetectionStrategy is one time binding solution. Why did angular team did not consider to include this feature? Did they see no performance benefit implementing this. If we are binding data only once like the titles and headers etc then one way binding is great to go right? Since we have less watchers for one time binding did they ignore it? Please let me know.

EDIT one time binding at property level is possible in angular 1 using {{::name}} but this was not included in angular 2. Why the syntax was removed. Any help is greatly appreciated

Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488
user3205479
  • 1,443
  • 1
  • 17
  • 41
  • I think there is one way binding, yo need to go to official document and read more – Aniruddha Das Sep 13 '17 at 20:10
  • You are contradicting yourself, you said you want one-time binding, yet you said `ChangeDetectionStrategy` is not providing what you need. SMH – Trash Can Sep 13 '17 at 20:12
  • `ChangeDetectionStrategy` is there for that. right! what else you need – Aniruddha Das Sep 13 '17 at 20:13
  • ChangeDetectionStrategy is for component. {{::hello}} works on the property one time binding itself – user3205479 Sep 13 '17 at 20:13
  • https://stackoverflow.com/questions/33327141/one-time-not-one-way-binding-for-inputs-in-angular2. can any one please tell me why one time binding was removed at property level rather than closing the question. please? – user3205479 Sep 13 '17 at 20:15
  • 5
    @user3205479, a good question and as often happens on SO downvoted because people don't know the answer. I upvoted. See [my answer](https://stackoverflow.com/a/46211205/2545680). – Max Koretskyi Sep 14 '17 at 05:31
  • @AniruddhaDas, there's no one time binding in Angular. `ChangeDetectionStrategy` is not one time binding. It affects entire component, not a single binding, and makes a component being checked as many times as required, not once. – Max Koretskyi Sep 14 '17 at 05:33
  • @Dummy, see my comment [above](https://stackoverflow.com/questions/46206027/why-no-one-time-binding-in-angular/46211205#comment79385414_46206027) – Max Koretskyi Sep 14 '17 at 05:35
  • @AngularInDepth.com when a component has `OnPush` strategy, its bindings are checked once during the initial change detection run, then itself and all of its child components will not be checked during subsequent change detection cycles, unless you mark them for checks – Trash Can Sep 14 '17 at 07:01
  • @Dummy, once the input property changes they will be checked without manual `markForCheck`. Also, `OnPush` doesn't only affect that current component, but all its children. What I'm saying is that `OnPush` is not in any way a replacement for one time binding – Max Koretskyi Sep 14 '17 at 07:02

1 Answers1

1

I believe it's because of the difference in implementation of the change detection mechanism.

In AngularJS you can dynamically add or remove watchers that update the DOM. For example, if you have the following template:

{{name}}

you can add the watcher:

const unwatch = $scope.$watch('name', () => { updateDOM() });

What's interesting is that AngularJS returns you the reference to the function that you can call to remove the watcher dynamically. And Angular itself uses this possibility to remove the watcher after the first call for one time bindings:

const unwatch = $scope.$watch('name', () => { if (!initial) unwatch(); updateDOM() });

However, in Angular the mechanism is different. The code that checks bindings is generated by the compiler statically and since a "watcher" is not added dynamically it cannot be removed dynamically. The generated function that performs DOM checks is called updateRenderer and you can read more about it in the article The mechanics of DOM updates in Angular. So for the binding:

{{name}}

The generated function will have the following body:

var _co = _v.component;
var currVal_0 = _co.name; // read value
_ck(_v,1,0,currVal_0);    // update DOM

And once generated, the function body can't be changed.

Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488
  • 1
    If {{name}} generates some static function body, cannot we generate {{::name}} a different function body statically for this syntax? While parsing template angular will check {{}} and search those properties and bind to watchers. Is not possible to bind one time using the {{::}} syntax? – user3205479 Sep 14 '17 at 11:00
  • @user3205479, yes, it's certainly possible, but you have to make considerable adjustments into the design of change detection system. My answer shows why that is not as easy as it was for AngularJS because of the static nature of code. – Max Koretskyi Sep 14 '17 at 12:28