Salesforce LWC学习(三十七) Promise解决progress-indicator的小问题

本篇参考://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的学习来说,前端如果好,解决问题的时候会方便不少。篇中有错误地方欢迎指出,有不懂欢迎留言。