我使用Angular Material 2 Stepper设置了一个线性步进器。
我在不同的组件中有表单(component-a,component-b,component-c)。在我的主容器组件(容器组件)中,我希望线性步进器在其表单有效时“逐步”遍历每个组件。
是否有某种功能可以与步进器中的stepControl
对话以使其正常工作?
我附上了步进器的文档和应用程序的StackBlitz版本。另外,我也有工作的回购链接。
物料步进器组件:https://material.angular.io/components/stepper/overview
StackBlitz:https://stackblitz.com/edit/angular-material2-issue-mjmu9u?file=app/app.component.ts
Github:https://github.com/sam11385
答案 0 :(得分:8)
我们遇到了完全相同的问题,经过几天的试验和错误后找到了一个有效的解决方案。基本上,由于步骤分为几个组件,每个组件都定义一个表单,并且它们对应的stepControl必须在父组件中,因此必须将子组件中的FormGroup发送到定义步进器的父组件。创建FormGroup之后,发出一个事件并让父级监听该事件,并通过该事件传递FormGroup。您可以为所有子项应用此项,为每个子项创建一个单独的事件,并为每个子项创建一个单独的侦听器。
宣布活动
@Output() notify: EventEmitter<FormGroup> = new EventEmitter<FormGroup>();
将formGroup发送到父组件
this.notify.emit(this.myFormGroup);
在组件(.ts)中,添加一个将接收和设置表单组的函数:
myFormGroup: FormGroup;
onNotify(formGroup: FormGroup): void {
this.myFormGroup = formGroup;
}
在html中,添加通知监听器:
<mat-step [completed]="false" [stepControl]="myFormGroup">
<ng-template matStepLabel>Step 1</ng-template>
<app-child (notify)='onNotify($event)'></app-child>
</mat-step>
嵌套组件说明:https://www.themarketingtechnologist.co/building-nested-components-in-angular-2/
答案 1 :(得分:2)
上面的答案很明显,但是在我的特定用例中我遇到了一些更深层次的问题,所以我用共享服务解决了这个问题:
<强>形状management.service.ts 强>
import { Injectable } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class FormManagementService {
private formSource: Subject<FormGroup> = new Subject();
locationForm: Observable<FormGroup> = this.formSource.asObservable();
formReady(form: FormGroup): void {
this.formSource.next(form);
}
}
<强> parent.component.ts 强>
import { Component } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { FormManagementService } from './form-management.service';
@Component({
....
providers: [ FormManagementService ]
})
export class ParentComponent {
form: FormGroup;
constructor(private formManagementService: FormManagementService) {
this.formManagementService.locationForm.subscribe(form => this.form = form);
}
}
注意,这里我们订阅了共享服务的更改,它将在需要时将表单传递给组件。当父组件收到表单时,它会填充FormGroup。
另请注意,我们在此处提供共享服务作为组件装饰器的一部分。您也可以在功能模块中提供它,如果这是您的代码的结构方式。
<强> child.component.ts 强>
import { Component } from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';
import { FormManagementService } from './form-management.service';
@Component({ ... })
export class ChildComponent {
form: FormGroup;
constructor(private formManagementService: FormManagementService,
private formBuilder: FormBuilder) {
this.form = this.formBuilder.group({});
this.formManagementService.formReady(this.form);
}
}
在子组件中,我们初始化表单,然后将其推送到共享服务,共享服务将在父组件中填充它。
注意,我发现如果我在构造函数以外的任何地方执行此操作,那么当我在ExpressionChangedAfterItHasBeenCheckedError
中执行此操作时,我遇到了ngAfterContentInit
,甚至。也许其他人会在我的解决方案上有进一步的进步来解决这个问题。
无论如何,希望这对那里的某些人有所帮助,因为这个问题困扰了我几个星期。