这是我原始问题的延续
stackoverflow.com/questions/44596418/angular-throws-expressionchangedafterithasbeencheckederror-with-textarea
尚未解决。我重新创建了orignal plunkr以模拟实际项目,发现它与textarea无关。
当我通过单击列表中的项目进入详细信息页面时,会抛出异常 ExpressionChangedAfterItHasBeenCheckedError 。仅当 src / detailitems.ts 的CodeView在数组中有多个元素时才会发生这种情况。 CodeView项以详细形式定义字段。
import { FormBase } from './formbase'
import { ItemBase, TextboxItemBase } from './itembase'
export class CodeView extends FormBase {
static getItems() :ItemBase[] {
let items: ItemBase[] = [
new TextboxItemBase(
{
key: 'id',
label: 'ID',
value: '',
required: true,
enabled: false,
readOnly: true,
size: 36
}
)
,
new TextboxItemBase(
{
key: 'description',
label: 'Description',
required: true,
size: 20
}
)
];
return items;
}
}
如果我修改代码以便CodeView只有1个项目,那么异常就会消失。
No Exception Plunkr(在详细资料中只有一项)
答案 0 :(得分:3)
您的错误来自A-Item
组件,更精确地来自此节点
<div [formGroup]="form"
当你有这样的绑定时,会自动创建NgControlStatusGroup
指令,根据控件状态设置CSS类(有效/无效/脏/等)。
export const ngControlStatusHost = {
'[class.ng-untouched]': 'ngClassUntouched',
'[class.ng-touched]': 'ngClassTouched',
'[class.ng-pristine]': 'ngClassPristine',
'[class.ng-dirty]': 'ngClassDirty',
'[class.ng-valid]': 'ngClassValid', // you get error in this binding
'[class.ng-invalid]': 'ngClassInvalid',
'[class.ng-pending]': 'ngClassPending',
};
您第一次没有为控件提供任何价值。这就是为什么您的表单valid
属性为false
的原因。然后在更改检测周期期间使用ngModel
填充它,并且形式为有效。 form
的有效属性是根据您的所有控件计算得出的。如果您只有一个控件,那么有效属性将仅依赖于一个控件,并且A-Item
组件不会引发错误。
我会在渲染之前准备数据。
您可以打开 form.component.ts 并找到以下代码
this.formItems.forEach(item => {
group[item.key] = item.BuildControl();
this.items.push(new formObjectItem(item, this.getData(item.key)));
});
然后你需要修补表格
的数据this.formItems.forEach(item => {
group[item.key] = item.BuildControl();
this.items.push(new formObjectItem(item, this.getData(item.key)));
group[item.key].patchValue(this.getData(item.key)); // <== this line
});
或
this.formItems.forEach(item => {
group[item.key] = item.BuildControl();
const value = this.getData(item.key);
this.items.push(new formObjectItem(item, value));
group[item.key].patchValue(value);
});
这样,您的表单将与您的价值同步并具有正确的状态。
在这种情况下,您还可以从itemValue
组件中删除ngModel
和A-Item
,因为被动模型将完成所有工作。
<强> Forked Plunker 强>
你没有得到这样的错误
还有一个提示:
import * as Rx from 'rxjs/Rx'
您将把所有rxjs库发送到您的包