Salesforce LWC學習(三十七) Promise解決progress-indicator的小問題

zero.zhang發表於2021-12-10

本篇參考:https://developer.salesforce.com/docs/component-library/bundle/lightning-progress-indicator/example

我們在實際專案中有的時候要使用展示類似opportunity path的這種進度的標籤,當然 lwc已經給做好了標籤和demo,我們第一版進行一個簡單的製作。直接上程式碼

testProgressIndicator.html

<template>
    <lightning-card title="path demo">
        <lightning-layout>
            <lightning-layout-item size="12" class="slds-float--right">
                <lightning-button onclick={handlePreviousStepAction} variant="brand" label="Previous" disabled={disablePrevious} class="slds-m-right_x-small slds-no-flex text-right ">
                </lightning-button>
                <lightning-button onclick={handleNextStepAction} variant="brand" label="Next" disabled={disableEnd} class="slds-m-right_x-small slds-no-flex text-right ">
                </lightning-button>
            </lightning-layout-item>
        </lightning-layout>
        <lightning-progress-indicator current-step={currentStep} type="path" >
            <template for:each={stepsForProgress} for:item="step">
                <lightning-progress-step label={step.label} value={step.value} key={step.label}></lightning-progress-step>
            </template>
        </lightning-progress-indicator>
    </lightning-card>
</template>

testProgressIndicator.js

import { LightningElement, track, wire } from 'lwc';
const testSteps = [
    { label: 'step1', value: 'step1' },
    { label: 'step2', value: 'step2' },
    { label: 'step3', value: 'step3' },
    { label: 'step4', value: 'step4' },
    { label: 'step5', value: 'step5' }
];
export default class testProgressIndicator extends LightningElement {
    @track stepsForProgress = testSteps;
    @track currentStep = 'step1';
    @track disablePrevious = true;
    @track disableEnd = false;

    renderedCallback() {
        if(this.currentStep === 'step1') {
            this.disablePrevious = true;
            this.disableEnd = false;
        } else if(this.currentStep === 'step5') {
            this.disablePrevious = false;
            this.disableEnd = true;
        } else {
            this.disablePrevious = false;
            this.disableEnd = false;
        }
    }

    handlePreviousStepAction() {
        let step = this.currentStep;
        this.currentStep = '';
        
        if(step === 'step2') {
            this.currentStep = 'step1';
        } else if(step === 'step3') {
            this.currentStep = 'step2';
        } else if(step === 'step4') {
            this.currentStep = 'step3';
        } else if(step === 'step5') {
            this.currentStep = 'step4';
        }
    }

    handleNextStepAction() {
        let step = this.currentStep;
        if(step === 'step1') {
            this.currentStep = 'step2';
        } else if(step === 'step2') {
            this.currentStep = 'step3';
        } else if(step === 'step3') {
            this.currentStep = 'step4';
        } else if(step === 'step4') {
            this.currentStep = 'step5';
        }
    }
}

演示效果:

初始化沒有問題

當點選一次next的時候,step1成功的變成了綠色,但是當又一次點選next的時候,我們發現step2沒有變成綠色。

 問題分析,可能實時的設定current step的值時,progress-indicator是非同步載入,所以渲染出現問題。

我們知道,js中的執行順序是 順序執行 > Promise > timeout非同步,所以我們優化一下程式碼,設定current step的值使用 Promise的方式設定。在 previous / next的函式中使用Promise的方式來搞定。

import { LightningElement, track, wire } from 'lwc';
const testSteps = [
    { label: 'step1', value: 'step1' },
    { label: 'step2', value: 'step2' },
    { label: 'step3', value: 'step3' },
    { label: 'step4', value: 'step4' },
    { label: 'step5', value: 'step5' }
];
export default class testProgressIndicator extends LightningElement {
    @track stepsForProgress = testSteps;
    @track currentStep = 'step1';
    @track disablePrevious = true;
    @track disableEnd = false;

    renderedCallback() {
        if(this.currentStep === 'step1') {
            this.disablePrevious = true;
            this.disableEnd = false;
        } else if(this.currentStep === 'step5') {
            this.disablePrevious = false;
            this.disableEnd = true;
        } else {
            this.disablePrevious = false;
            this.disableEnd = fale;
        }
    }

    handlePreviousStepAction() {
        let step = this.currentStep;
        this.currentStep = '';
        const previousStepPromise = () =>
        new Promise((resolve, reject) => {
            resolve(step);
        });

        previousStepPromise()
        .then((result) => {
            if(step === 'step2') {
                this.currentStep = 'step1';
            } else if(step === 'step3') {
                this.currentStep = 'step2';
            } else if(step === 'step4') {
                this.currentStep = 'step3';
            } else if(step === 'step5') {
                this.currentStep = 'step4';
            }
        });
    }

    handleNextStepAction() {
        let step = this.currentStep;
        const nextStepPromise = () =>
        new Promise((resolve, reject) => {
            resolve(step);
        });
        this.currentStep = '';

        nextStepPromise()
        .then((result) => {
            if(result === 'step1') {
                this.currentStep = 'step2';
            } else if(result === 'step2') {
                this.currentStep = 'step3';
            } else if(result === 'step3') {
                this.currentStep = 'step4';
            } else if(result === 'step4') {
                this.currentStep = 'step5';
            }
        });
    }
}

結果展示:現在效果就是正常的了。

總結:我們在lwc的使用中,除了這個以外,關於以前 datatable翻頁篇也同樣使用Promise的方式來解決了問題。lwc的學習來說,前端如果好,解決問題的時候會方便不少。篇中有錯誤地方歡迎指出,有不懂歡迎留言。

相關文章