Проверьте несколько требуемых LWC на одном экране потока БЕЗ потери значений

#javascript #salesforce #lwc

Вопрос:

Поэтому я недавно начал более серьезно заниматься LWC и пытаюсь во всем этом разобраться. Я создал пользовательский компонент потока списков выбора, который принимает набор строк в качестве опций (почему это не стандартно, я никогда не узнаю). Мне удалось предотвратить переход на следующую страницу, если компонент помечен как «Необходимый» с помощью @api validate() .

Однако проблема заключается в том, что если несколько из этих компонентов находятся на одном экране, и один из них не проходит проверку; тогда все компоненты (даже допустимые) сбрасывают свои значения после отображения очень краткого значка загрузки. Я хотел бы как можно ближе имитировать стандартную требуемую функциональность компонента/поля экрана, чтобы избежать разочарований при вводе и несоответствий.

Ниже приведен мой текущий код:

component.js

 import { LightningElement, api, track } from 'lwc';

export default class StringPicklistFlowComponent extends LightningElement {
    @api optionsArr;
    @api label;
    @api isRequired = false;
    @api value;

    get isNotRequired(){return !this.isRequired;}

    get options(){
        var arr = [];
        for(var i = 0; i < this.optionsArr.length; i  ){
            var tmp = this.optionsArr[i].split(/,s*/g);
            arr.push({label: tmp[0], value: tmp[1]});
        }
        return arr;
    }

    handleSelect(evt){
        this.value = evt.detail.value;
    }

    @api validate(){
        return {
            isValid: this.isNotRequired || this.value != null,
            errorMessage: "Please select an option"
        }
    }
}
 

component.html

 <template>
    <label for="customPicklist" class="slds-form-element__label slds-rich-text-editor__output">
        <span class="slds-required" hidden={isNotRequired}>*</span>
        {label}
    </label>
    <lightning-combobox id="customPicklist" value={value} options={options} onchange={handleSelect}>
    </lightning-combobox>
</template>
 

Обратите внимание, что я действительно создал метку вручную. Это связано с тем, что функция по умолчанию, когда поле было непосредственно помечено как «требуется», постоянно отображала ошибку поля, в то время как значение компонента было равно нулю, что немного раздражает.

Любая помощь в этом была бы потрясающей, так как это мучило меня большую часть дня.

Ответ №1:

Мне удалось найти решение, поэтому я опубликую его здесь на случай, если кто-нибудь еще столкнется с этой проблемой. В основном проблема сводится к тому, что компонент повторно визуализируется и, следовательно, теряет свои предыдущие данные. Чтобы обойти это, вы можете использовать собственный браузер sessionStorage для хранения значений, а затем при повторной визуализации использовать connectedCallback хук для установки значения компонента. Вот как теперь выглядит мой код:

component.js

 import { LightningElement, api, track } from 'lwc';

export default class StringPicklistFlowComponent extends LightningElement {
    @api isRequired = false;
    @api optionsArr;
    @api label;
    @api value;

    @api connectedCallback(){
        if(!!sessionStorage[this.storageTag])
            this.value = sessionStorage[this.storageTag];
        else
            sessionStorage[this.storageTag] = this.value;
    }

    get storageTag(){ return this.label   'myTag5135'; }

    get isNotRequired(){ return !this.isRequired; }

    get options(){
        var arr = [];
        for(var i = 0; i < this.optionsArr.length; i  ){
            var tmp = this.optionsArr[i].split(/,s*/g);
            arr.push({label: tmp[0], value: tmp[1]});
        }
        return arr;
    }

    handleSelect(evt){
        this.value = evt.detail.value;
        sessionStorage[this.storageTag] = this.value;
    }

    @api validate(){
        return {
            isValid: this.isNotRequired || !!this.value,
            errorMessage: "Please select an option"
        };
    }
}
 

component.html

 <template>
    <div>
        <label for="customPicklist" class="slds-form-element__label">
            <abbr class="slds-required" hidden={isNotRequired}>* </abbr>{label}
        </label>
        <lightning-combobox dropdown-alignment="auto" id="customPicklist" data-fieldname={label} variant="label-hidden" value={value} options={options} onchange={handleSelect}>
        </lightning-combobox>
    </div>
</template>
 

Если вы заметите, я использую свойство label, которое не является идеальным (нет гарантии, что оно уникально). Я хотел бы использовать имя api компонентов в потоке, чтобы практически гарантировать уникальность, однако мне еще предстоит найти, как получить это свойство по умолчанию в компоненте. Если кто-нибудь знает, как это сделать, я был бы очень признателен. В любом случае, я надеюсь, что это поможет всем, у кого были подобные разочарования из-за этого странного ограничения по умолчанию.