$cache[$key] = empty($arr) ? NULL : $arr; return $cache[$key]; } // 门户 获取需要在频道显示的栏目主题数据 function portal_channel_thread($fid) { global $forumlist; if (empty($fid)) return NULL; $orderby = array('tid' => 1); $page = 1; // 遍历所有在频道显示内容的栏目 $category_forumlist = channel_category($fid); $arrlist = array(); $forum_tids = array(); $tidlist = array(); if ($category_forumlist) { foreach ($category_forumlist as &$_forum) { // 频道显示数据 $arrlist['list'][$_forum['fid']] = array( 'fid' => $_forum['fid'], 'name' => $_forum['name'], 'rank' => $_forum['rank'], 'type' => $_forum['type'], 'url' => $_forum['url'], 'channel_new' => $_forum['channel_new'], ); $forum_thread = thread_tid__find(array('fid' => $_forum['fid']), $orderby, $page, $_forum['channel_new'], 'tid', array('tid')); // 最新信息按栏目分组 foreach ($forum_thread as $key => $_thread) { $forum_tids[$key] = $_thread; } unset($forum_thread); } $tidlist += $forum_tids; } unset($category_forumlist); // 获取属性对应的tid集合 list($flaglist, $flagtids) = flag_thread_by_fid($fid); empty($flagtids) || $tidlist += $flagtids; unset($flagtids); // 频道置顶 $stickylist = sticky_list_thread($fid); empty($stickylist) || $tidlist += $stickylist; // 在这之前合并所有二维数组 tid值为键/array('tid值' => tid值) $tidarr = arrlist_values($tidlist, 'tid'); // 在这之前使用$tidarr = array_merge($tidarr, $arr)前合并所有一维数组 tid/array(1,2,3) if (empty($tidarr)) { $arrlist['list'] = isset($arrlist['list']) ? array_multisort_key($arrlist['list'], 'rank', FALSE, 'fid') : array(); return $arrlist; } $tidarr = array_unique($tidarr); $pagesize = count($tidarr); // 遍历获取的所有tid主题 $threadlist = well_thread_find_asc($tidarr, $pagesize); // 遍历时为升序,翻转为降序 $threadlist = array_reverse($threadlist); foreach ($threadlist as &$_thread) { // 各栏目最新内容 isset($forum_tids[$_thread['tid']]) AND $arrlist['list'][$_thread['fid']]['news'][$_thread['tid']] = $_thread; // 全站置顶内容 isset($stickylist[$_thread['tid']]) AND $arrlist['sticky'][$_thread['tid']] = $_thread; // 首页属性主题 if (!empty($flaglist)) { foreach ($flaglist as $key => $val) { if (isset($val['tids']) && in_array($_thread['tid'], $val['tids'])) { $arrlist['flaglist'][$key][array_search($_thread['tid'], $val['tids'])] = $_thread; ksort($arrlist['flaglist'][$key]); $arrlist['flag'][$_thread['tid']] = $_thread; } } } } unset($threadlist); if (isset($arrlist['sticky'])) { $i = 0; foreach ($arrlist['sticky'] as &$val) { ++$i; $val['i'] = $i; } } if (isset($arrlist['flag'])) { $i = 0; foreach ($arrlist['flag'] as &$val) { ++$i; $val['i'] = $i; } } if (isset($arrlist['flaglist'])) { foreach ($arrlist['flaglist'] as &$val) { $i = 0; foreach ($val as &$v) { ++$i; $v['i'] = $i; } } } isset($arrlist['list']) AND $arrlist['list'] = array_multisort_key($arrlist['list'], 'rank', FALSE, 'fid'); return $arrlist; } ?>javascript - Pass the data to next step in component based mat-stepper - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Pass the data to next step in component based mat-stepper - Stack Overflow

programmeradmin0浏览0评论

I am using a component-based mat stepper component to display a linear process. Each step have own component as below

<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>

I am using a component-based mat stepper component to display a linear process. Each step have own component as below

<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>

Step-1 shows the multi selectable list of items and pass selected item list to the next step-2 and add a quantity of each item in step-2.

How to pass selected items on Next click from step-1 to step-2 and display passed item to enter a quantity in step-2?

I have created a common service layer to set and get selected items. ngOnInit of a component of step-2 trying to get the selected list from common service but issue is component-2 is already initiated before the next click.

Can do initialize or re-initialize the second component after the click of next in step-1?

How to display the selected items list in step-2 after moving from step-1?

What will be the best approach for the above scenario?

Just a link to any reference that can answer my question, it should be enough.

Thank you.

Share Improve this question asked Mar 3, 2020 at 13:22 Vijay VavdiyaVijay Vavdiya 1,3091 gold badge13 silver badges20 bronze badges 1
  • are you still looking for solutions or found one?? – Aravind Commented Mar 10, 2020 at 17:58
Add a comment  | 

4 Answers 4

Reset to default 8 +100

To make a component to output a value use @Output.

To consume data from outside a component, use @Input.

As I don't know the type of your item I'll use ItemType in this example.

select-item-component

Inside select-item-component, declare an attribute:

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

and when the select changes, just do

this.onDataChange.emit(formValue);

add-qty-component

@Input() item: ItemType;

If you want to trigger some actions when the value changes, use set. For example:

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

You could do the same in select-item-component with select1 and select2 variables.

parent

Use the output and the input values.

...
<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>
...

You can use a combination of @Output and @Input decorators.

@Output decorator can be used in the child component (stepper 1) to transmit the data to its parent component.

@input decorator can be used to send that data from the parent component to the child component (stepper 2).

You can read more about it here.

You can use ControlContainer for the same purpose which allows you to access the form controls both in the child component as well as in the parent component

<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>

Your Step1 component should look like

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));
  }
}

Your Step2 component will look like

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

Another option is to use a shared service. I would use a Subject on the service, and call next in the component that changes the data, passing the new data on the next call.

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

Then in the next component, subscribe to your Subject and set your local variable to that data.

this.sharedService.$itemsAdded.subscribe(items => {
  this.items = items.map(x => mapItem());
});
发布评论

评论列表(0)

  1. 暂无评论