12
votes

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.

1
Yes, *ngIf is the correct syntax, I have updated the post to show this. My mistake.ClarAng

1 Answers

16
votes

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();
}