[英]Cannot Bind Dynamic Data in Component Angular 8
Error when component loading dynamic 动态加载组件时出错
DynamicBuilderComponent.ngfactory.js:198 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
DynamicBuilderComponent.ngfactory.js:198错误错误:ExpressionChangedAfterItHasBeenCheckedError:检查表达式后,表达式已更改。 Previous value: 'ng-pristine: true'.
以前的值:'ng-pristine:true'。 Current value: 'ng-pristine: false'.
当前值:“ ng-pristine:false”。
Problem 问题
after binding json in select2data to select2 component Angular throw exception.
component code 组件代码
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'select2',
Imported changeDetection in component. 在组件中导入了changeDetection。
template: `
<div [formGroup]="form">
<ng-container>
<ng-select2
[data]="select2data"
[options]="options"
[width]="500"
[formControlName]="field.code"
(keyup)="changed($event.target.value)">
</ng-select2>
</ng-container>
</div>`
})
select2 component class select2组件类
export class Select2Component implements OnInit {
@Input() field: any = {};
@Input() form: FormGroup;
public exampleData: Array<Select2OptionData>;
public options: Options;
public value: string[];
select2data: any;
public selected: string;
constructor(public cl: Services,private cd: ChangeDetectorRef) {
this.options = {
width: '258',
multiple: true,
tags: false
};
}
Problem Area After Binding subscribe data in ng select2 component 绑定后的问题区域在ng select2组件中订阅数据
changed(search: any) {
//call service pass search text to service
return this.cl.searchFunc(search).subscribe(
res1 =>
this.select2data = res1.data;
this.cd.markForCheck(); // marks path
}
}
},
error => {
console.log('error = ', error);
});
}
}
i tried to print this.select2data in console.log its return me json. 我试图在console.log中打印this.select2data它返回我json。
Vendor.js Vendor.js
function expressionChangedAfterItHasBeenCheckedError(context, oldValue, currValue, isFirstCheck) {
var msg = "ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '" + oldValue + "'. Current value: '" + currValue + "'.";
if (isFirstCheck) {
msg +=
" It seems like the view has been created after its parent and its children have been dirty checked." +
" Has it been created in a change detection hook ?";
}
return viewDebugError(msg, context);
}
Great Article 好文章
https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html
Reference 参考
Expression ___ has changed after it was checked 表达式___在检查后已更改
I believe that you put your component select2
inside another component which contains a form which you then pass to select2
for create another <form>
tag, is that correct? 我相信您将组件
select2
放在另一个包含表单的组件内,然后将其传递给select2
以创建另一个<form>
标记,对吗? I mean do you have something like that? 我的意思是你有那样的东西吗?
<form [formGroup]="form">
<!-- Some code -->
<select2 [field]="something" [form]="form"></select2>
</form>
If so, then your select2
component SHOULD NOT contain re-declaration of form, it should not contain anything related to forms at all. 如果是这样,那么您的
select2
组件不应包含表单的重新声明,它根本不应该包含与表单相关的任何内容。 It should be a form control. 它应该是一个表单控件。 Please read a post by Netanel Basal on how to create custom form controls.
请仔细阅读后如何创建自定义窗体控件通过Netanel基础。 You will need to create
ControlValueAccessor
for your select2
and wire it up to Angular forms through a custom provider. 您将需要为
select2
创建ControlValueAccessor
,然后通过自定义提供程序将其连接到Angular表单。
The issue you're facing is that since you include form
object twice in the DOM data changes are propagated twice as well and you run into issues. 您面临的问题是,由于您在DOM中两次包含了
form
对象,因此数据更改也被传播了两次,并且遇到了问题。 There should be only one reference to a specific instance of FormGroup
in your templates. 模板中应该仅对
FormGroup
的特定实例有一个引用。
Solution that worked 有效的解决方案
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'select2',
export class Select2Component implements OnInit {
constructor(public cl: Services,private cd: ChangeDetectorRef) {
this.options = {
width: '258',
multiple: true,
tags: false
};
}
Binding function 装订功能
changed(search: any) {
//call service pass search text to service
return this.cl.searchFunc(search).subscribe(
res1 =>
this.select2data = res1.data;
this.cd.markForCheck(); // marks path
this.cd.detectChanges();
}
}
},
error => {
console.log('error = ', error);
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.