I have made a variation of an example app from an Angular book.
A working example (in development mode) can be found here: http://ng-ex.watchduck.net/#/21
The source code can also be found on GitHub.
The component log
has the variable autoRefresh
. (see here)
export class LogComponent implements OnInit {
autoRefresh: boolean = false;
constructor(private changeDetector: ChangeDetectorRef) { }
ngOnInit() {
this.changeDetector.detach(); // Here is the problem.
}
render() {
this.changeDetector.reattach();
this.changeDetector.detectChanges();
this.changeDetector.detach();
}
start() { this.autoRefresh = true; }
stop() { this.autoRefresh = false; }
}
I would like to use it in the component (in the green box) to show the current status, and to disable two buttons based on it. (see here) But that does not work. No initial value is shown, and then it just sticks with the first value.
<button (click)="start()" [disabled]="autoRefresh">start</button>
<button (click)="stop()" [disabled]="!autoRefresh">stop</button>
But when I place the buttons outside of the component it works. (see here)
<button (click)="viewer.start()" [disabled]="viewer.autoRefresh">start</button>
<button (click)="viewer.stop()" [disabled]="!viewer.autoRefresh">stop</button>
<app-log #viewer [logs]="logs"></app-log>
This is quite counter-intuitive, right? What is going wrong here?
Edit: The problem goes away, when I remove this.changeDetector.detach();
from ngOnInit
.
But of course having it there is the point of this exercise.
To clarify: If the disabled
attributes were removed, the start and stop button in the component would work fine. What fails is binding the variable autoRefresh
to the disabled
attributes (as well as using it with ngSwitch
or just showing it with {{autoRefresh}}
).
Obviously you have omitted - before edit - the most important part of the code which is ngoninit in your case....
When you do 'detach'you are simply excludiong current instance of component from angulars change detection cycle. Because od that, you dont see the effects of setting value of 'autorefresh' as angular doesnt bother to reflect that change.
You effectively almost use onPush detrction strategy by detaching yourself from thr change detector.
When you are placing your buttons outside of the component, the host componemt IS in the change detection cycle therefore you ca see that ui reflects that change.
To verify this, detach the parent component from the change detection ref and you will see exactly the same results