我有一个材料步进机,在步进机的每个步骤中都有表格。在那里,每个步骤都应由与其关联的表单控制。
即使已经在SO中提出了这个问题,但这些问题的答案仍无法解决我的问题。因此,我问。
父HTML
<mat-horizontal-stepper linear #stepper>
<mat-step [stepControl]="frmStepOne">
<ng-template matStepLabel>Step One Details</ng-template>
<app-first-step #stepOne></app-first-step>
</mat-step>
<mat-step [stepControl]="frmStepTwo">
<ng-template matStepLabel>Step Two Details</ng-template>
<app-second-step #stepTwo></app-second-step>
</mat-step>
</mat-horizontal-stepper>
在我的父组件中,我有以下人。
@ViewChild('stepOne') stepOneComponent: FirstStepComponent;
@ViewChild('stepTwo') stepTwoComponent: SecondStepComponent;
get frmStepOne() {
return this.stepOneComponent ? this.stepOneComponent.frmStepOne : null;
}
get frmStepTwo() {
return this.stepTwoComponent ? this.stepTwoComponent.frmStepTwo : null;
}
我的孩子班级组件
frmStepOne: FormGroup;
constructor(private formBuilder: FormBuilder) {
this.frmStepOne = this.formBuilder.group({
name: ['', Validators.required]
});
}
子类HTML
<mat-card>
<form [formGroup]="frmStepOne">
<mat-form-field>
<input matInput formControlName="name" matInput placeholder="Name" required>
</mat-form-field>
<mat-card-actions>
<button mat-raised-button matStepperNext class="nav-btn pull-right">Next</button>
</mat-card-actions>
</form>
</mat-card>
现在,当我运行应用程序时,在控制台中,我看到以下内容。
错误错误:ExpressionChangedAfterItHasBeenCheckedError:表达 检查后已更改。上一个值:“ stepControl:空”。 当前值:“ stepControl:[object Object]”。
正如我之前提到的,SO中对此进行了讨论。例如,答案和以下链接的问题的注释建议将窗体初始化移至构造函数,而不是将其放在onInit中。我已经做到了。
Angular Material Stepper Component For Each Step
但是,我仍然收到错误消息。
这是我在Stackblitz上的项目-https://stackblitz.com/github/vigamage/stepper-component-wise
有人可以建议如何解决这个问题吗?
谢谢..
答案 0 :(得分:4)
基本上,角度已将两个值都设置为null
后才检测到变化。因此,您需要明确告诉angular它应该运行更改检测。 Check out this demo code
我删除了使用get
的逻辑,因为直接从HTML调用函数是一种不好的做法。它会被多次调用。尝试将控制台日志放入代码中,然后查看。
我已经使用ngAfterViewInit
和ChangeDetectorRef
进行通知。
export class AppComponent implements AfterViewInit {
title = 'mat-stepper';
form1: FormGroup;
form2: FormGroup;
@ViewChild('stepOne') stepOneComponent: FirstStepComponent;
@ViewChild('stepTwo') stepTwoComponent: SecondStepComponent;
constructor(private cdr :ChangeDetectorRef){}
ngAfterViewInit(){
this.form1 = this.stepOneComponent.frmStepOne;
this.form2 = this.stepTwoComponent.frmStepTwo
this.cdr.detectChanges();
}
}
这将解决错误
答案 1 :(得分:2)
只需将导致此错误的变量更改为Observable
,然后用pipe
delay(0)
将其更改为operator
这是有效的解决方案link-没有错误,不需要使用更改检测。
这是一个例子
假设我在name
模板中使用了string
类型的变量html
,它会导致上述错误。
<div>{{ name }}</div> // BOOM ERROR why?
因为起初name
是某种东西,在角度检查之后它就被更改了。
因此要解决此问题..首先将name
更改为Observable
之类的name$
name$: Observable<string>; // name$ replaces name
private myName$ = new BehaviorSubject<string>();
myNameListener$: Observable<string> = this.myName$.asObservable();
myName(name: string) {
this.myName$.next(name)
}
现在在ngOnInit()
中,只需收听可观察到的声音
ngOnInit() {
this.name$ = this.myNameListener$.pipe(
delay(0)
)
}
使用Observable
管道在html
模板中订阅async
<div *ngIf=" (name$ | async) as name ">{{ name }}</div> // render your variable
现在将您的实际数据传递到您想观察的任何地方。
this.myName(data);
这是有效的解决方案link-没有错误,不需要使用更改检测。
祝你好运!