0

我使用角材料步进器。我从后端获取数据,根据这些数据我应该设置特定的步骤。我使用 [selectedIndex] 指令,但 selectedIndex 不适用于我传递给它的值。setTimeout 我试过了,它对我不起作用。SelectedIndex 等于 0。为什么 selectedIndex 不适用于 currentStep?以及如何解决这个问题?

    <mat-horizontal-stepper
    #stepper
    [selectedIndex]="currentStep"
    [linear]="true"
>
    <mat-step #step1 [completed]="step1.interacted || 0 < currentStep" [stepControl]="stepConfirmation.formGroup">
        <ng-template matStepLabel>Contact Info</ng-template>
        <fo-new-customer-confirmation-info #stepConfirmation></fo-new-customer-confirmation-info>
    </mat-step>
    <mat-step #step2 [completed]="step2.interacted || 1 < currentStep" [stepControl]="stepBusiness.formGroup">
        <ng-template matStepLabel>Business Info</ng-template>
        <fo-new-customer-business-info #stepBusiness></fo-new-customer-business-info>
    </mat-step>
    <mat-step #step3 [completed]="step3.interacted || 2 < currentStep" [stepControl]="stepApplicant.formGroup">
        <ng-template matStepLabel>Applicant Info</ng-template>
        <fo-new-customer-applicant-info #stepApplicant></fo-new-customer-applicant-info>
    </mat-step>
    <mat-step #step4 [completed]="step4.interacted || 3 < currentStep" [stepControl]="stepFinancial.formGroup">
        <ng-template matStepLabel>Financial Review</ng-template>
        <fo-new-customer-financial-review-info #stepFinancial></fo-new-customer-financial-review-info>
    </mat-step>
</mat-horizontal-stepper>
<footer class="row">
    {{stepper.selectedIndex}}
    <div>
        <button
            mat-button
            mat-flat-button
            *ngIf="stepper.selectedIndex !== 0"
            (click)="preview()"
            color="accent">
            Previous
        </button>
        <button
            class="mb-3 mb-sm-0 ml-auto"
            mat-button
            mat-flat-button
            color="primary"
            [ladda]="isDataUploading"
            *ngIf="stepper.selectedIndex !== stepper.steps?.length-1"
            (click)="next()">
            Next
        </button>
    </div>
</footer>

export class NewCustomerStepperComponent implements AfterViewInit {
    public stepperManager: StepperManager = {
        steps: {
            [StepperState.ContactInfoOrganic]: {
                control: null,
            },
            [StepperState.BusinessInfoOrganic]: {
                control: null,
            },
            [StepperState.ApplicantInfoOrganic]: {
                control: null,
            },
            [StepperState.FinancialReviewOrganic]: {
                control: null,
            },
        },
    };
public currentStep: number;
    public emptyGuid: string = '00000000-0000-0000-0000-000000000000';
    public isStepperStateWasChanged: boolean = false;
    public isDataUploading: boolean = false;
    @ViewChild('stepper', {static: true})
    public stepper: MatStepper;

    @ViewChild('stepConfirmation', {static: true})
    public stepConfirmationInfo: NewCustomerConfirmationInfoComponent;

    @ViewChild('stepBusiness', {static: true})
    public stepBusinessInfo: NewCustomerBusinessInfoComponent;

    @ViewChild('stepApplicant', {static: true})
    public stepApplicantInfo: NewCustomerApplicantInfoComponent;

    @ViewChild('stepFinancial', {static: true})
    public stepFinancialInfo: NewCustomerFinancialReviewInfoComponent;

    constructor(
        private readonly notificationService: NotificationService,
        private readonly formService: FormService,
        private readonly dataService: NewCustomerFormStepperDataService,
        private readonly authService: AuthService,
        private readonly navigationService: NavigationService,
    ) {
    }

    public ngAfterViewInit(): void {
        this.stepperManager.steps[StepperState.ContactInfoOrganic].control
            = this.stepConfirmationInfo;
        this.stepperManager.steps[StepperState.BusinessInfoOrganic].control
            = this.stepBusinessInfo;
        this.stepperManager.steps[StepperState.ApplicantInfoOrganic].control
            = this.stepApplicantInfo;
        this.stepperManager.steps[StepperState.FinancialReviewOrganic].control
            = this.stepFinancialInfo;
            this.redirectAccordingToStatus();

    }

    // public onStepChange(event: StepperSelectionEvent): void {
    //  // if (!this.isStepperStateWasChanged) {
    //  //  this.isStepperStateWasChanged = true;
    //  //  return;
    //  // }
    //  event.selectedStep.interacted = false;
    //  this.loadStepDataById(event.selectedIndex);
    // }

    public preview(): void {
        this.stepper.previous();
    }

    public next(): void {
        if (this.formService.isFormValid(
            this.stepperManager.steps[this.stepper.selectedIndex].control.formGroup)
        ) {
            this.isDataUploading = true;
            this.stepperManager.steps[this.stepper.selectedIndex].control
                .submit()
                .pipe(
                    take(1),
                )
                .subscribe(
                    () => {
                        this.isDataUploading = false;
                        this.stepper.next();
                        this.loadStepDataById(this.stepper.selectedIndex);
                    },

                );
        }
    }

    public setStepper(index: number): void {
        this.currentStep = index;
        this.stepper.selectedIndex = this.currentStep;
        this.loadStepDataById(index);

    }

    private mapLeadStatusToStepperState(status: LeadStatusRequest): number {
        return StepperState[status.value];
    }

    private loadStepDataById(id: number): void {
        this.stepperManager.steps[id].control
                .getData();
    }

    private getStatus(): Observable<LeadStatusRequest> {
        return this.dataService
            .getStatus()
            .pipe(
                take(1),
            );
    }

    private redirectAccordingToStatus(): void {
        this.getStatus()
            .subscribe(
                status => {
                    const id: number = status.id;

                    switch (id) {
                        case NewCustomerStatus.ContactInfoOrganic:
                        case NewCustomerStatus.BusinessInfoOrganic:
                        case NewCustomerStatus.ApplicantInfoOrganic:
                        case NewCustomerStatus.FinancialReviewOrganic:
                            this.currentStep = this.mapLeadStatusToStepperState(status);
                            this.setStepper(this.currentStep);
                            break;

                        default:
                            this.navigationService.navigateToErrorPage();
                    }
                },

            );
    }

}
4

1 回答 1

2

因为您已将线性设置为 true,所以步进器索引不会改变。在您的 ts 文件中,您需要将线性设置为 false,然后将 index 设置为您想要的任何值,然后添加 setTimeout 并将线性更改为 true。所以:

public setStepper(index: number): void {
    this.stepper.linear = false
    this.currentStep = index;
    this.stepper.selectedIndex = this.currentStep;
    setTimeout(() => {
        this.stepper.linear = true;
    });
    this.loadStepDataById(index);
}

这应该可以解决问题。

此外,如果您希望在直接跳转到特定步骤时将之前的步骤显示为已完成,那么您需要执行以下操作:

public setStepper(index: number): void {
    this.stepper.linear = false
    this.currentStep = index;
    while (this.stepper.selectedIndex < this.currentStep) {
        this.stepper.selectedIndex += 1;
    }
    this.stepper.selectedIndex = this.currentStep;
    setTimeout(() => {
        this.stepper.linear = true;
    });
    this.loadStepDataById(index);
}

在这里,“while”循环会将所有索引一一设置为您首选索引之前的 selectedIndex。这样,您就可以欺骗步进器,使其相信它已与所有先前的步骤进行了交互,并且会将它们标记为已完成。

于 2020-06-16T12:17:08.137 回答