Угловая форма для многоразового использования с отдельными шагами в качестве компонентов

#angular #angular-material #angular-material-stepper

#угловая #угловой-материал #угловой шаговый шагатель для материалов

Вопрос:

Я использую Angular Material stepper, и он отлично работает как весь код в 1 компоненте. Но шаговый механизм будет использоваться в ~ 10 разных компонентах. Существует 7 различных типов форм, таких как ввод, выбор, имя, таблица и т. Д. Итак, я понял, что я разделю шаговый шаг на отдельные компоненты, где каждый компонент является шагом. Итак, я решил сделать шаблон для формы app-step-form

 <form [formGroup]="myForm">
  <mat-vertical-stepper [linear]="isLinear" #stepper>
      <ng-content></ng-content>
  </mat-vertical-stepper>
</form>
 

Чем создавать разные шаги, подобные этому, в app-table-select

   <mat-step [stepControl]="tableControl">
    <ng-template matStepLabel>Table </ng-template>
    <mat-form-field appearance="fill">
      <mat-label>Choose table</mat-label>
      <mat-select [formControl]="tableControl">
        <mat-option *ngFor="let table of tables" [value]="table.value">
          {{table.viewValue}}
        </mat-option>
      </mat-select>
    </mat-form-field>
    <div>
      <button mat-button matStepperNext>Next</button>
    </div>
  </mat-step>
 

и чем вставлять компоненты в виде таких шагов

 <app-step-from>

  <app-table-select>
  </app-table-select>

  <app-name-input>
  </app-name-input>

</app-step-from>
 

Поэтому у меня был бы шаблон для формы для использования в разных компонентах, чтобы не создавать каждый раз по одному.

Но проблема, с которой я сталкиваюсь, заключается в том, что если я использую пошаговый компонент, как показано выше, он не виден app-step-form . Внесение небольших изменений app-step-form и извлечение <mat-step></mat-step> из этого

 <form [formGroup]="myForm">
  <mat-vertical-stepper [linear]="isLinear" #stepper>
    <mat-step>
      <ng-content></ng-content>
    </mat-step>
  </mat-vertical-stepper>
</form>
 

и извлекать mat-step и вставлять его <ng-template> вот так

 <ng-template>
    <ng-template matStepLabel>Table </ng-template>
    <mat-form-field appearance="fill">
      <mat-label>Choose table</mat-label>
      <mat-select>
        <mat-option *ngFor="let table of tables" [value]="table.value">
          {{table.viewValue}}
        </mat-option>
      </mat-select>
    </mat-form-field>
</ng-template>
 

делает этот шаг видимым в app-step-form , но не может передать метку компонента шага из
<ng-template matStepLabel>Table </ng-template> и эта метка не видна или @Input() не используется.

Я потратил 2 дня, пытаясь взломать это, ища answear, но пока не так хорошо, и потерял представление о том, как преодолеть эту проблему, чтобы сделать мой шаговый механизм многоразовым.

У кого-нибудь есть идеи, как заставить эту идею работать? Или невозможно сделать так, как я понял?

Также есть идеи, как заставить эти входные данные действовать как часть 1 формы? Подчиненные формы объединены в 1 форму или что?

Ответ №1:

Для кого это может касаться — я не нашел никакого решения этой проблемы.

Я попытался создать 1 многоразовый компонент со всеми возможными входными данными в нем и отобразить каждый вход в нем с помощью директивы *ngIf в зависимости от пути, где он находится, например:

<app-step-form [path]='/your-path'></app-step-from> и каждый путь имеет все возможные входные данные, но оказалось, что у него много неожиданных уязвимостей. Многие поля, которые не были обязательными, делали пустую вставку в базу данных без необходимости (где вы могли и должны избегать), поэтому…

Я решил создать каждую форму отдельно, используя каждый независимый компонент с помощью:

     this.parentForm = this.fb.group({
      records: new FormControl(null,
        [
          Validators.required,
          Validators.min(2),
          Validators.max(255),
          Validators.pattern('^(0|[1-9][0-9]*)

Каждый ввод в качестве компонента содержал в себе валидаторы, поэтому не беспокойтесь о проверке поля pf в каждой форме.
Пример:

 <form [formGroup]="parentForm">
  <mat-vertical-stepper [linear]="isLinear" #stepper>
    <mat-step [stepControl]="parentForm">
      <ng-template matStepLabel>Records</ng-template>
      <app-material-input [parentForm]="parentForm"></app-material-input>
      <div>
        <app-mat-stepper-next-button></app-mat-stepper-next-button>
      </div>
    </mat-step>
    <mat-step [stepControl]="parentForm">
      <ng-template matStepLabel>Value</ng-template>
      <app-material-input [parentForm]="parentForm"></app-material-input>
      <div>
        <app-mat-stepper-next-button></app-mat-stepper-next-button>
      </div>
    </mat-step>
    <mat-step>
      <ng-template matStepLabel>We're done!</ng-template>
      <app-mat-stepper-back-button></app-mat-stepper-back-button>
      <button mat-flat-button (click)="onSubmit(parentForm)">Submit</button>
    </mat-step>
  </mat-vertical-stepper>
</form>
 

Родительская форма в родительском компоненте:
parentForm: FormGroup

в дочернем компоненте: @Input() parentForm: FormGroup;

И это все. Это можно было бы сделать с помощью 1 формы, отображающей входные данные в зависимости от параметров или пути, но имеет больше смысла создавать отдельную форму с помощью FormBuilder , а не иметь 1 форму для каждого места, которое этого требует.



)
],
),
value: new FormControl(null),
});

Каждый ввод в качестве компонента содержал в себе валидаторы, поэтому не беспокойтесь о проверке поля pf в каждой форме.
Пример:


Родительская форма в родительском компоненте:
parentForm: FormGroup

в дочернем компоненте: @Input() parentForm: FormGroup;

И это все. Это можно было бы сделать с помощью 1 формы, отображающей входные данные в зависимости от параметров или пути, но имеет больше смысла создавать отдельную форму с помощью FormBuilder , а не иметь 1 форму для каждого места, которое этого требует.