记录angular8 ngModel双向绑定页面不生效问题

839 阅读1分钟

框架:angular8
ui组件:NG-ZORRO
问题:switch开关,通过js改变开关状态,html视图不生效
代码:
html:

<nz-switch nzCheckedChildren="启动" nzUnCheckedChildren="停止" name="status"  
            [nzDisabled]="isSwitchState[item.vname]"  [nzLoading]="isSwitchState[item.vname]"
            [(ngModel)]="item.status" (ngModelChange)="changeState(item)">
 </nz-switch>

ts:

image.png

image.png

image.png

现象: 在changeState()方法中,如图,修改item.status的状态,只有标红框处修改页面视图状态不生效,在subscribe方法中基础修改是生效的,经查询,是由于angualr的变更检测影响,至于具体影响机制,我还没有特别离清楚,需后续在对ChangeDetectorRef进一步了解学习。

解决方案:在更新switch的状态前,调用this.cd.detectChanges()进行手动触发变更检测。

概念:

export declare abstract class ChangeDetectorRef {
    abstract checkNoChanges(): void; 
    abstract detach(): void;
    abstract detectChanges(): void;
    abstract markForCheck(): void;
    abstract reattach(): void;
}
export abstract class ViewRef extends ChangeDetectorRef {
   ...
}

如上代码所示,changeDetectorRef包含以下方法:
checkNoChanges: 在运行当前的变更检测时,确保没有变化发生;
detach: 禁用掉对当前视图的检查;
detectChanges: 在当前视图和他的子视图只允许一次变更检测(是手动触发变更检测的方法之一);
markForCheck:对所有父组件一直到根组件都启用脏检查;
reattach:把以前分离开的视图重新附加到变更检测树上。视图会被默认附加到这颗树上。

以下两篇文章是我在解决问题时看到的,主要是讲angular变更检测机制的,想深入学习的可以了解:

juejin.cn/post/684490…
juejin.cn/post/699211…