Передача данных на следующий шаг в компоненте mat-stepper - PullRequest
1 голос
/ 03 марта 2020

Я использую компонентный матовый шаговый компонент для отображения линейного процесса. Каждый шаг имеет собственный компонент, как показано ниже

<mat-card>
    <mat-horizontal-stepper [linear]="isLinear" labelPosition="bottom" #stepper>
    
    <!-- Step-1 -->
    <mat-step [stepControl]="firstFormGroup">
       <ng-template matStepLabel>Select Items</ng-template>
       <select-item-component>
       <select-item-component>
       <div class="mt-5">
          <button mat-flat-button color="primary" matStepperNext>Next</button>
       </div>
    </mat-step>
    
    <!-- Step-2 -->
    <mat-step [stepControl]="firstFormGroup">
       <ng-template matStepLabel>Add Quantity</ng-template>
       <add-qty-component>
       <add-qty-component>
       <div class="mt-5">
          <button mat-flat-button color="primary" matStepperNext>Next</button>
       </div>
    </mat-step>
    
    <!-- Step-3 -->
    <mat-step [stepControl]="firstFormGroup">
       <ng-template matStepLabel>Conform</ng-template>
       <conform-step-component>
       <conform-step-component>
       <div class="mt-5">
          <button mat-flat-button color="primary" matStepperNext>Done</button>
       </div>
    </mat-step>
    </mat-horizontal-stepper>
 </mat-card>

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

Как передать выбранные позиции при следующем щелчке от шага 1 к шагу 2 и отобразить пропущенный элемент для ввода количества в шаге 2?

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

Может выполнить инициализацию или повторную инициализацию второго компонента после щелчок «Далее» в шаге 1?

Как отобразить список выбранных элементов в шаге 2 после перехода из шага 1?

Каким будет наилучший подход для вышеуказанного сценария?

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

Спасибо.

Ответы [ 4 ]

3 голосов
/ 05 марта 2020

Вы можете использовать комбинацию декораторов @Output и @Input.

@ Выходной декоратор может использоваться в дочернем компоненте (шаговый 1) для передачи данных в его родительский компонент.

@ Input Decorator может использоваться для отправки этих данных из родительского компонента в дочерний компонент (шаговый 2).

Подробнее об этом можно прочитать здесь .

2 голосов
/ 09 марта 2020

Чтобы заставить компонент выводить значение, используйте @Output.

Чтобы использовать данные извне компонента, используйте @Input.

Поскольку я не знаю тип вашего элемента, я буду использовать ItemType в этом примере.

select-item-component

Внутри select-item-component объявите атрибут :

@Output() onDataChange: EventEmitter<ItemType> = new EventEmitter();

и когда выбор изменяется, просто выполните

this.onDataChange.emit(formValue);

add-qty-component

@Input() item: ItemType;

Если вы хотите вызвать некоторые действия, когда значение изменяется, используйте set. Например:

@Input() set item(value: ItemType) {
  this.loadOptions(value);
}

Вы можете сделать то же самое в select-item-component с переменными select1 и select2.

parent

Использовать выходные данные и входные данные значения.

...
<select-item-component (onDataChange)="select1 = $event"></select-item-component>
<select-item-component (onDataChange)="select2 = $event"></select-item-component>

...

<add-qty-component [item]="select1"></add-qty-component>
<add-qty-component [item]="select2"></add-qty-component>
...
1 голос
/ 06 марта 2020

Вы можете использовать ControlContainer для той же цели, которая позволяет получить доступ к элементам управления формы как в дочернем компоненте, так и в родительском компоненте

<button mat-raised-button (click)="isLinear = !isLinear" id="toggle-linear">
  {{!isLinear ? 'Enable linear mode' : 'Disable linear mode'}}
</button>
<mat-horizontal-stepper [linear]="isLinear" #stepper>
  <mat-step [stepControl]="firstFormGroup">
    <form [formGroup]="firstFormGroup">
      <ng-template matStepLabel>Fill out your name</ng-template>
     <step1></step1>
      <div>
        <button mat-button matStepperNext>Next</button>
      </div>
    </form>
  </mat-step>
  <mat-step [stepControl]="secondFormGroup">
    <form [formGroup]="secondFormGroup">
      <ng-template matStepLabel>Fill out your address</ng-template>
      <step2></step2>
      <div>
        <button mat-button matStepperPrevious>Back</button>
        <button mat-button matStepperNext>Next</button>
      </div>
    </form>
  </mat-step>
</mat-horizontal-stepper>

Ваш компонент Step1 должен выглядеть следующим образом

import {Component, OnInit} from '@angular/core';
import {ControlContainer, FormGroup, Validators} from '@angular/forms';


@Component({
  selector: 'step1',
  template:`
  <form [formGroup]="form"> 
   <mat-form-field>
        <mat-label>Name</mat-label>
        <input matInput placeholder="Last name, First name" formControlName="firstCtrl" required>
      </mat-form-field>
  </form>
  `
})
export class Step1 implements OnInit {
  isLinear = false;
  form: FormGroup;

  constructor(private controlContainer:ControlContainer) {}

  ngOnInit() {
   this.form=<FormGroup>this.controlContainer.control;
   this.form.valueChanges.subscribe(data=>console.log(data));
  }
}

Ваш Step2 компонент будет выглядеть как

import {Component, OnInit} from '@angular/core';
import {ControlContainer, FormGroup, Validators} from '@angular/forms';

/**
 * @title Stepper overview
 */
@Component({
  selector: 'step2',
  template:`
  <form [formGroup]="form"> 
    <mat-form-field>
        <mat-label>Address</mat-label>
        <input matInput formControlName="secondCtrl" placeholder="Ex. 1 Main St, New York, NY"
               required>
      </mat-form-field>
  </form>
  `
})
export class Step2 implements OnInit {
  form: FormGroup;

  constructor(private controlContainer:ControlContainer) {}

  ngOnInit() {
   this.form=<FormGroup>this.controlContainer.control;
   this.form.valueChanges.subscribe(data=>console.log(data));
  }
}

stackblitz

0 голосов
/ 05 марта 2020

Другим вариантом является использование общего сервиса. Я хотел бы использовать Subject в службе и вызывать next в компоненте, который изменяет данные, передавая новые данные при следующем вызове.

public $itemsAdded: Subject<Item> = new Subject<Item>();

Затем в следующем компоненте подпишитесь на свой предмет и установите для локальной переменной эти данные.

this.sharedService.$itemsAdded.subscribe(items => {
  this.items = items.map(x => mapItem());
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...