Angular 2+ one-time binding
I found solution for one time binding in angular 2 here: https://github.com/angular/angular/issues/14033
I created this directive:
import { Directive, TemplateRef, ViewContainerRef, NgZone } from "@angular/core";
@Directive({
selector: '[oneTime]',
})
export class OneTimeDirective {
constructor(template: TemplateRef<any>, container: ViewContainerRef, zone: NgZone) {
zone.runOutsideAngular(() => {
const view = container.createEmbeddedView(template);
setTimeout(() => view.detach());
})
}
}
And used it:
<some-selector *oneTime [somePropertyToOneTimeBinding]="someValueToOneTimeBinding"></some-selector>
For example:
<iframe *oneTime [src]="myUrl"></iframe>
ChangeDetectionStrategy.CheckOnce
is the solution for this problem.
Some info here:
http://www.syntaxsuccess.com/viewarticle/change-detection-in-angular-2.0
https://angular.io/docs/ts/latest/api/core/index/ChangeDetectionStrategy-enum.html
Currently, you cannot do one time binding with Angular 2. However, you can know when your binding changes and reset your inputs.
Angular 2 provides OnChanges lifecycle hook for the same. You need to implement OnChanges interface to get the changes.
See the code example below where, I am storing the data-bound property in a private variable when OnInit is called.
export class Footer implements OnInit, OnChanges {
@Input() public name: string;
private privname: string;
constructor() { }
ngOnInit() {
this.privname = this.name;
}
ngOnChanges(changes: { [key: string]: SimpleChange }): void {
if (!changes["name"].isFirstChange()) {
this.name = this.privname;
}
}
}
Later when other changes occur, I am setting the value to its old value on subsequent changes.
This mechanism works like One-time binding.
Alternate solutions: You could also use a setter function to capture the changes.
ChangeDetectionStrategy.CheckOnce is the solution for this problem.
This has been updated to OnPush
see also comment in code:
export declare enum ChangeDetectionStrategy {
/**
* `OnPush` means that the change detector's mode will be set to `CheckOnce` during hydration.
*/
OnPush = 0,
/**
* `Default` means that the change detector's mode will be set to `CheckAlways` during hydration.
*/
Default = 1,
}