首页 文章

角度 - 角度材料2步进控制

提问于
浏览
3

我使用Angular Material 2 Stepper设置了一个线性步进器 .

我有不同组件中的表单(组件-a,组件-b,组件-c) . 在我的主容器组件(容器组件)中,我希望线性步进器在其表单有效时“逐步”遍历每个组件 .

是否有某种功能可以与步进器中的 stepControl 进行对话以使其正常工作?

我附上了步进器的文档和应用程序的StackBlitz版本 . 此外,我也有工作的回购链接 .

Material Stepper组件: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

2 回答

  • 5

    我们遇到了完全相同的问题,经过几天的反复试验后找到了可行的解决方案 . 基本上,由于步骤分为几个组件,每个组件都定义一个表单,并且它们对应的stepControl必须在父组件中,因此必须将子组件中的FormGroup发送到定义步进器的父组件 . 创建FormGroup之后,发出一个事件并让父级监听该事件,并通过该事件传递FormGroup . 您可以为所有子项应用此项,为每个子项创建一个单独的事件,并为每个子项创建一个单独的侦听器 .

    在子组件中:

    • 宣布该事件
    @Output() notify: EventEmitter<FormGroup> = new EventEmitter<FormGroup>();
    
    • 将formGroup发送到父组件
    this.notify.emit(this.myFormGroup);
    

    在包含mat-stepper的stepControl的父组件中:

    • 在组件(.ts)中,添加一个将接收和设置formgroup的函数:
    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

    上面的答案很明显,但是在我的特定用例中我遇到了一些更深层次的问题,所以我用共享服务解决了这个问题:

    form-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 中执行了此操作 . 也许其他人会在我的解决方案上有进一步的进步来解决这个问题 .

    无论如何,希望这对那里的某些人有所帮助,因为这个问题困扰了我几个星期 .

相关问题