簡體   English   中英

從嵌套組件調用時,Angular Material 步進器不會進行下一步。 (角 11)

[英]Angular Material stepper not proceeding to next step when being called from nested component. (Angular 11)

打電話時

this.stepper.next()

使用子組件上的按鈕,直到第二次單擊按鈕時步進器才會進行。

父組件 Html

<mat-card>
  <mat-card-header>Test</mat-card-header>
  <mat-card-content>
    <mat-horizontal-stepper #stepper linear>
      <mat-step [completed]='this.CheckIfStepCompleted(1)'>
        <mat-card>
          <mat-card-content>
            <app-comp1 [steps]='this.steps'></app-comp1>
          </mat-card-content>
          <mat-card-actions align='start'>
           <!-- <button mat-raised-button matStepperNext color='primary' [disabled]='!this.CheckIfStepCompleted(1)'>Next</button> -->
          </mat-card-actions>
        </mat-card>
      </mat-step>
      <mat-step [completed]='this.CheckIfStepCompleted(2)'>
        <mat-card>
          <mat-card-content>
            <app-comp2 [steps]='this.steps'></app-comp2>
          </mat-card-content>
          <mat-card-actions align='start'>
            <button mat-raised-button matStepperNext color='primary' [disabled]='!this.CheckIfStepCompleted(2)'>Next</button>
          </mat-card-actions>
        </mat-card>
      </mat-step>
      <mat-step [completed]='this.CheckIfStepCompleted(2)'>
        <mat-card>
          <mat-card-content>
            <app-comp3 [steps]='this.steps'></app-comp3>
          </mat-card-content>
          <mat-card-actions align='start'>
            <button mat-raised-button matStepperPrevious color='primary' [disabled]='!this.CheckIfStepCompleted(2)'>Back</button>
          </mat-card-actions>
        </mat-card>
      </mat-step>
    </mat-horizontal-stepper>
  </mat-card-content>
</mat-card>

子組件 Html

  <button (click)='this.Complete()' mat-raised-button color='accent'>Complete</button>

子組件 ts 文件

import { Component, Input, NgZone, OnInit, ViewChild, ViewChildren } from '@angular/core';
import { MatHorizontalStepper } from '@angular/material/stepper';
import { Step, SteppperService } from '../../services/stepper/steppper.service';

@Component({
  selector: 'app-comp1',
  templateUrl: './comp1.component.html',
  styleUrls: ['./comp1.component.css']
})
export class Comp1Component implements OnInit {

  @Input() steps: Step[] = [];

  constructor(private _stepSvc: SteppperService, private readonly stepper: MatHorizontalStepper, private ngZone: NgZone) { }
  selectedIndex: number = this.stepper.selectedIndex;
  ngOnInit(): void {
  }
  Complete() {
    this._stepSvc.CompleteStep(this.steps, 1).then(() => this.stepper.next());
    // this.ProgressStep();
  }
  ProgressStep() {
    this.ngZone.run(() => {
      this.stepper.next();
    });
  }
}

我們還嘗試在父組件上創建一個函數,並從子組件發出一個事件來觸發 next()。

TLDR:我需要為位於父組件上的步進器觸發 next(),但我需要從子組件觸發它。

嘗試在子組件上添加輸出並處理父組件中的點擊。 輸入用於將數據從父級向下傳遞到子級。 所以你會有類似的東西:

import { Component, Input, NgZone, OnInit, ViewChild, ViewChildren } from '@angular/core';
import { MatHorizontalStepper } from '@angular/material/stepper';
import { Step, SteppperService } from '../../services/stepper/steppper.service';

@Component({
  selector: 'app-comp1',
  templateUrl: './comp1.component.html',
  styleUrls: ['./comp1.component.css']
})
export class Comp1Component implements OnInit {

  @Input() steps: Step[] = [];
  @Output() handleChange = new EventEmitter<boolean>(); // create the event

  constructor(private _stepSvc: SteppperService, private readonly stepper: MatHorizontalStepper, private ngZone: NgZone) { }
  selectedIndex: number = this.stepper.selectedIndex;
  ngOnInit(): void {
  }
  Complete() {
    this._stepSvc.CompleteStep(this.steps, 1).then(() => this.stepper.next());
    // this.ProgressStep();
  }
  ProgressStep() {
    this.ngZone.run(() => {
      this.stepper.next();
      this.handleChange.emit(true); // trigger the event
    });
  }
}

然后在父級中,您可以處理該更改,例如:

<Comp1Component (handleChange)="processTheChangeFromTheParent($event)">...

所以我讓它工作了。 我能夠使用 Akkonrad 的答案,但這並不是最終奏效的方法。

最終我不得不在模板磁貼上使用“已完成”屬性。

我發現在 ngAfterViewInit() 上,我將作為 ViewChild 訪問步進器,然后遍歷步驟並將它們全部設置為 Completed=false。

然后,如果我在子組件上使用 EventEmitter,我可以觸發父組件上步驟的完成。 他們的關鍵是我不能使用該屬性以這種方式工作。 它只能由 ts 文件控制。

現在對我來說,這似乎是一個錯誤。 話雖如此,我只有一年的角度,而且我還不是專家。 如果有人能解釋為什么會這樣,我很想知道。

工作代碼如下:

父 html:

<mat-card>
  <mat-card-header>Test</mat-card-header>
  <mat-card-content>
    <mat-horizontal-stepper #stepper linear>
      <mat-step>
        <mat-card>
          <mat-card-content>
            <app-comp1 (CompleteStep)='this.CompleteStep(0)'></app-comp1>
          </mat-card-content>
        </mat-card>
      </mat-step>
      <mat-step>
        <mat-card>
          <mat-card-content>
            <app-comp2 (CompleteStep)='this.CompleteStep(1)'></app-comp2>
          </mat-card-content>
        </mat-card>
      </mat-step>
      <mat-step>
        <mat-card>
          <mat-card-content>
            <app-comp3 (CompleteStep)='this.CompleteStep(2)'></app-comp3>
          </mat-card-content>
        </mat-card>
      </mat-step>
    </mat-horizontal-stepper>
  </mat-card-content>
</mat-card>

家長 TS:

import { Component, OnInit, ViewChild, AfterViewInit, ViewEncapsulation } from '@angular/core';
import { MatStepper } from '@angular/material/stepper';

@Component({
  selector: 'app-step',
  templateUrl: './step.component.html',
  styleUrls: ['./step.component.css'],
  encapsulation: ViewEncapsulation.None
})
export class StepComponent implements OnInit, AfterViewInit {

  @ViewChild('stepper', { static: false }) stepper: MatStepper;

  constructor() { }

  ngOnInit() {
  }

  ngAfterViewInit() {
    this.Initialize()
  }
  Initialize() {
    this.stepper.steps.forEach(Step => {
      Step.completed = false;
    });
  }

  CompleteStep(stepNumer: number) {
    debugger;
    this.stepper.steps.get(stepNumer).completed = true;
    this.stepper.next();
  }

}

子HTML:

  <button (click)='this.Complete()' mat-raised-button color='accent'>Complete</button>

兒童 TS:

import { Component, EventEmitter, OnInit, Output } from '@angular/core';

@Component({
  selector: 'app-comp1',
  templateUrl: './comp1.component.html',
  styleUrls: ['./comp1.component.css']
})
export class Comp1Component implements OnInit {

  @Output() CompleteStep = new EventEmitter<any>();

  constructor() { }

  ngOnInit(): void {
  }

  Complete() {
    this.CompleteStep.emit();
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM