[英]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.