zoukankan      html  css  js  c++  java
  • Salesforce LWC学习(十七) 前端知识之 onclick & onblur & onmousedown

    Salesforce LWC学习(八) Look Up组件实现篇中,我们实现了公用的lookup组件,使用的过程中,会发现当我们输入内容以后,搜索出来的列表便无法被清空。

     针对此种情况我们打算优化一下代码,针对前端的输入框,增加onblur函数,当鼠标移除情况下,设置searchTerm为空字符串并且不让下方的options展示,当鼠标移入或者输入内容情况下在展示下方的options.

    customLookUpForLwc.html:输入框添加onblur,下方options使用变量控制显隐

    <template>
        <div>
            <div class="slds-form-element">
                <div class="slds-form-element__control">
                    <div class="slds-combobox_container">
                        <div id="box" class={boxClass} aria-expanded="true" aria-haspopup="listbox" role="combobox">
                            {searchLabel}
                            <div class="slds-combobox__form-element slds-input-has-icon slds-input-has-icon_right" role="none">
                                <template if:true={isValue}>
                                    <div id="lookup-pill" class="slds-pill-container">
                                        <lightning-pill class="pillSize" label={valueObj} name={valueObj} onremove={handleRemovePill}>
                                            <lightning-icon icon-name={iconName} alternative-text="acc" ></lightning-icon>
                                        </lightning-pill>
                                    </div>
                                </template>
                                <template if:false={isValue}>
                                    <div class="slds-p-top_none">
                                        <lightning-input class={inputClass} type="search" id="input" value={searchTerm}
                                            onclick={handleClick}  onchange={onChange}
                                            onblur={handleBlurEvent}
                                            variant="label-hidden" autocomplete="off" placeholder="Search..." label='account search'>
                                        </lightning-input>
                                    </div>
                                </template>
                            </div>
                            <template if:true={isEnableShowOptions}>
                                <div id="listbox-id-1" class="slds-dropdown slds-dropdown_length-with-icon-7 slds-dropdown_fluid" role="listbox">
                                    <ul class="slds-listbox slds-listbox_vertical" role="presentation">
                                        <template for:each={options} for:item="item">
                                            <li key={item.Id} onclick={onSelect} data-id={item.Id} role="presentation">
                                                <span class="slds-lookup__item-action slds-lookup__item-action--label" role="option">
                                                    <lightning-icon class="slds-icon slds-icon--small slds-icon-text-default" icon-name={iconName} alternative-text={objName} size="small"></lightning-icon>
                                                    <span class="slds-truncate">{item.Name}</span>
                                                </span>
                                            </li>
                                        </template>
                                    </ul>
                                </div>
                            </template>
                            
                        </div>
                    </div>
                </div>
            </div>
        </div>
    
    </template>

    customLookUpForLwc.js:搜索结果处增加处理项,同时增加是否显隐标签的判断逻辑

    /* eslint-disable no-console */
    /* eslint-disable @lwc/lwc/no-async-operation */
    
    import lookUp from '@salesforce/apex/CustomLookUpForLwcController.lookUp';
    import { getObjectInfo } from 'lightning/uiObjectInfoApi';
    import { getRecord } from 'lightning/uiRecordApi';
    import { api, LightningElement, track, wire } from 'lwc';
    
    export default class CustomLookUpForLwc extends LightningElement {
        //store object record id
        @api valueId;
        //record API name
        @api objName;
        //record icon name,see Lightning Design System to choose
        @api iconName;
    
        @api filter = '';
        //unique key used to mark the unique component. several component use this component need to mapping
        @api uniqueKey;
        //used to set the field to fetch.eg: ['Account.Name'] means we need to search account name field as filter
        @api fields;
    
        //search label show in lookup component
        @api searchLabel;
    
        @track searchTerm = '';
        //record name value
        @track valueObj;
        //record href
        @track href;
        //fetch result
        @track options;
        //fetch result backup
        @track optionsBackup;
        //is available value to show in lightning-pill
        @track isValue = false;
        //indicator if enable show options
        @track isEnableShowOptions = true;
    
        //css
        @track boxClass = 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-has-focus';
        @track inputClass = '';
    
        @wire(lookUp, {searchTerm : '$searchTerm', myObject : '$objName', filter : '$filter'})
        wiredRecords({ error, data }) {
            if (data) {
                this.record = data;
                this.error = undefined;
                if(this.searchTerm && this.isEnableShowOptions) {
                    this.options = this.record;
                } else if(this.isEnableShowOptions) {
                    if(!this.optionsBackup) {
                        this.optionsBackup = this.record;
                    }
                    this.options = this.optionsBackup;
                }
            } else if (error) {
                this.error = error;
                this.record = undefined;
            }
        }
    
        //To get preselected or selected record
        @wire(getRecord, { recordId: '$valueId', fields: '$fields' })
        wiredOptions({ error, data }) {
            if (data) {
                this.record = data;
                this.error = undefined;
                this.valueObj = this.record.fields.Name.value;
                this.href = '/'+this.record.id;
                this.isValue = true;
            } else if (error) {
                this.error = error;
                this.record = undefined;
            }
        }
    
        handleClick() {
            
            this.searchTerm = '';
            this.isEnableShowOptions = true;
            this.inputClass = 'slds-has-focus';
            this.boxClass = 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-has-focus slds-is-open';
        }
    
        onSelect(event) {
            console.log("In onSelect");
            let ele = event.currentTarget;
            let selectedId = ele.dataset.id;
            //As a best practise sending selected value to parent and inreturn parent sends the value to @api valueId
            let key = this.uniqueKey;
            const valueSelectedEvent = new CustomEvent('valueselect', {
                detail: { selectedId, key },
            });
            this.dispatchEvent(valueSelectedEvent);
            this.boxClass = 'slds-combobox slds-dropdown-trigger slds-dropdown-trigger_click slds-has-focus';
        }
    
        onChange(event) {
            this.searchTerm = event.target.value;
            this.isEnableShowOptions = true;
        }
    
        handleBlurEvent() {
            this.isEnableShowOptions = false;
            this.searchTerm = '';
        }
    
        handleRemovePill() {
            this.isValue = false;
            let selectedId = '';
            let key = this.uniqueKey;
            const valueSelectedEvent = new CustomEvent('valueselect', {
                detail: { selectedId, key },
            });
            this.dispatchEvent(valueSelectedEvent);
        }
    
    }

    我们修改以后运行结果为:当我们输入内容onblur失去焦点时,确实实现了下方内容隐藏,但是当我们输入内容有结果选中下方item时,item也并没有选中而是同样出现了下方内容隐藏的效果。这个是什么原因呢?

    这个时候需要考虑的一点就是标准事件的执行顺序问题,标准事件中,我们常用的有 onclick / onblur,大家都知道onclick 是按钮按压以后执行,onblur是元素失去焦点以后执行。相当于onclick 为 onmousedown -> onmouseup这两个操作以后作为onclick,onblur在onmousedown以后,但是在onmouseup以前,也就是说Onblur在onclick操作以前,所以上述的demo中,下面的ul li的onclick事件无法调用到只能调用到input的onblur的事件,针对这种情况我们最终只需要将li的事件从onclick 修改成onmousedown即可完美的解决上述的问题。

     总结:篇中主要是通过优化共通方法来引出 onclick / onblur 的执行顺序问题以及提出如何解决此种问题的方案,知识点很简单,纯粹前端知识,篇中有错误地方欢迎指出,有不懂欢迎留言。

  • 相关阅读:
    状态模式
    简单密码再次加密
    服务层定义自己的服务异常类
    必备网络基础知识(持续补充)
    MongoDB基础入门
    Git命令整理
    算法基础(四)
    RabbitMQ消息队列
    设计模式(23种)
    二叉树知识点
  • 原文地址:https://www.cnblogs.com/zero-zyq/p/12950433.html
Copyright © 2011-2022 走看看