我对垫选择列表和反应形式有疑问。 问题是我创建了垫选择列表,然后从本地存储中读取后,更新了表单。一切正常,但我收到ExpressionChangedAfterItHasBeenCheckedError,因为它显然是使用默认值创建的。这是预期的行为吗?如果是,该如何解决呢?
您可以在此处看到堆栈闪电示例:
https://stackblitz.com/edit/angular-ul58q4
答案 0 :(得分:2)
此错误是因为您设置了表单初始值,但视图无法检测到它,因此在设置初始值后使用changeDetectorRef
将会是正确的:
import { Component, AfterViewInit, Injectable ,ChangeDetectorRef } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { LocalStorageService } from './local-storage.service';
const FILTER_FORM_STORAGE_KEY = 'filterFormStorageKey';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
formGroup: FormGroup;
typesControl: FormControl;
types: any[] = [
{ id: 1, name: 'Type A' },
{ id: 2, name: 'Type B' }
];
constructor(private _storage: LocalStorageService,
private changeDetectorRef: ChangeDetectorRef) {
this.formGroup = new FormGroup({
typesControl: this.typesControl = new FormControl(null, [Validators.required])
});
}
ngAfterViewInit(): void {
const formStorage = this._storage.get(FILTER_FORM_STORAGE_KEY);
if (formStorage) {
this.formGroup.patchValue(formStorage);
}
this.changeDetectorRef.detectChanges();
}
saveForm() {
console.log('submitted');
this._storage.set(FILTER_FORM_STORAGE_KEY, this.formGroup.value);
}
}
正在工作DEMO。
答案 1 :(得分:1)
我们无法在stackblitz中查看源代码。问题是您正在更新DOM之后更新组件对象。您还需要手动触发更改检测以更新DOM。使用
setTimeout(()=>{
}, 0);