Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Component variable change not updated in view until mouseover in Angular 2

After updating from angular2-alpha to the latest version, the changes of a boolean are not updating a *ngIf until certain actions are performed.

Here is the component in question:

declare var CKEDITOR: any;
export class FieldComponent {

 @Input() field: any = {};
 ckeditor: any;
 editable: boolean = false;

 constructor(){

  this.switchToUnEditable();

  this.listenForEvent("FieldEditableEvent", (data) => {
    this.switchToEditable();
  });

 }

 switchToEditable(){
  this.ckeditor.destroy();
  this.ckeditor = CKEDITOR.replace(this.field.id);
  this.editable = true;
 }

switchToUnEditable() {
  if(this.ckeditor) {
   this.ckeditor.destroy();
  }
  this.ckeditor = CKEDITOR.replace(this.field.id, {
   toolbar: []
  })
  this.editable = false;
 }



}

And here is the template for this component:

<div *ngIf="editable" class="green-background white-text unlocked">
  This field is unlocked!
  <button (click)="switchToUnEditable()"> 
   Save and close. 
  </button>
</div>
<div *ngIf="!editable" class="red-background white-text locked">
  This field is locked!
</div>
<textarea [attr.name]="field.id" [(ngModel)]="field.value">  
</textarea>

This used to work perfectly fine before the update - now I have to mouseover the button inside the div to get the *ngIf to be applied in the view.

Alternatively, I can perform an event further up the component tree and the *ngIf will be applied at that point also. For example, opening the side-nav changes the view from locked to unlocked.

Is this the correct change detection to be expected in Angular 2 - If so, how do I make the user aware that the field is locked or unlocked before they perform an event that updates the view.

like image 942
ClarAng Avatar asked Oct 13 '16 12:10

ClarAng


People also ask

What triggers change detection in angular?

By default, angular will run the change detector every time @Input() data is changed or modified. But with OnPush strategy, the change detector is only triggered if the data passed on @Input() has a new reference.

How does angular update the DOM?

It basically takes the current value passed from the updateRenderer function and compares it to the value from the previous change detection. A View holds old values in the oldValues property. If the value changed Angular uses the updated value to compose a string and update the DOM using a renderer.

What is change detection and how it is handled?

Change detection is the process through which Angular checks to see whether your application state has changed, and if any DOM needs to be updated. At a high level, Angular walks your components from top to bottom, looking for changes.

How angular components are destroyed?

To force a component to be destroyed, you use the HostListener from the Angular Core library. When using HostListener , you specify the event you want to listen to on the host of the component. In our case, we listen for the unloaded event so that when the page is unloaded, ngOnDestroy() will be triggered.


1 Answers

It seems the call to switchToEditable() and switchToUnEditable() are somehow made outside of Angulars zone.

If you invoke change detection explicitly it should work:

constructor(private cdRef:ChangeDetectorRef) {}

switchToEditable(){
  this.editable = true;
  this.cdRef.detectChanges();
}

switchToUnEditable() {
  ...
  this.editable = false;
  this.cdRef.detectChanges();
}
like image 145
Günter Zöchbauer Avatar answered Sep 21 '22 23:09

Günter Zöchbauer