Salesforce LWC学习(十) 前端处理之 list 处理

本篇参看:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array

list是我们经常要处理的内容,lwc前端针对list主要有几个函数处理,不同函数针对不同场景有不同的功能。下面就根据几个常用的处理list的方法进行简单的介绍。

一. forEach

我们针对list处理经常需要迭代去处理,通常可能用到for(var index = 0;index < sampleList.length; index++)这种方式,其实我们可以直接通过forEach函数去搞定,功能以及操作和上述方式相同。有几个参数可供选择。

/*
(method) Array<number>.forEach(callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any): void
Performs the specified action for each element in an array.
@param callbackfn — A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array.
@param thisArg — An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/

下面通过一个demo来进行了解。

forEachSample.html:展示几个输入框,点击cancel以后会将所有的字段输入内容清空。

<template>
    <lightning-record-edit-form
        record-id={recordId}
        object-api-name="Contact">
            <lightning-messages></lightning-messages>
            <lightning-input-field field-name="FirstName"></lightning-input-field>
            <lightning-input-field field-name="LastName"></lightning-input-field>
            <lightning-input-field field-name="Email"></lightning-input-field>
            <lightning-input-field field-name="Phone"></lightning-input-field>
            <div class="slds-align_absolute-center slds-p-around_medium">
                <lightning-button class="slds-m-around_xx-small" label="Cancel" onclick={handleReset}></lightning-button>
                <lightning-button class="slds-m-around_xx-small" label="Create Contact" type="submit" variant="brand" ></lightning-button>
            </div>
    </lightning-record-edit-form>
</template>

forEachSample.js:handleReset方法首先先获取到所有的lightning-inut-field然后使用forEach,这里只用了field,不需要用index,然后 =>方式 {}括起来去进行处理,reset是lightning-input-field的封装的方法,感兴趣的可以自行查看,lightning-input & lightning-input-field有很多好用的方法,后期有机会可以单独抽出来一篇博客讲解。

import { LightningElement,api } from ‘lwc‘;

export default class ForEachSample extends LightningElement {
    @api recordId;
    handleReset(event) {
        const inputFields = this.template.querySelectorAll(
            ‘lightning-input-field‘
        );
        if (inputFields) {
            inputFields.forEach(field => {
                field.reset();
            });
        }
     }
}

二. find & findIndex

find和findIndex在lwc中针对list处理会经常用到,用于列表针对某一个条件去查找匹配的数据,匹配上则返回第一条匹配的数据然后终止遍历,如果没有匹配值则返回undefined, findIndex用于列表针对某一个条件去查找匹配的数据,匹配上返回第一条匹配的数据的下标然后终止遍历,下标从0开始,如果没有匹配则返回-1.我们可以根据find / findIndex来做那种选择列表中选择指定一条以后显示那条的数据信息或者获取那条数据详细信息,根据ID作为条件的遍历。demo找的是官方的一个功能,代码如下:

ContactController.cls:简单的获取list的列表数据

public with sharing class ContactController {
    @AuraEnabled(cacheable=true)
    public static List<Contact> getContactList() {
        return [SELECT Id, Name, Title, Phone, Email FROM Contact LIMIT 10];
    }
}

eventWithData.html:上面是一个list,点击以后触发事件获取到指定的那条数据然后展示在另一个区域

<template>
    <lightning-card title="EventWithData" icon-name="standard:logging">
        <template if:true={contacts.data}>
            <lightning-layout class="slds-m-around_medium">
                <lightning-layout-item>
                    <template for:each={contacts.data} for:item="contact">
                        <c-contact-list-item
                            key={contact.Id}
                            contact={contact}
                            onselect={handleSelect}
                        ></c-contact-list-item>
                    </template>
                </lightning-layout-item>
                <lightning-layout-item class="slds-m-left_medium">
                    <template if:true={selectedContact}>

                        <p>{selectedContact.Name}</p>
                        <p>{selectedContact.Title}</p>
                        <p>
                            <lightning-formatted-phone
                                value={selectedContact.Phone}
                            ></lightning-formatted-phone>
                        </p>
                        <p>
                            <lightning-formatted-email
                                value={selectedContact.Email}
                            ></lightning-formatted-email>
                        </p>
                    </template>
                </lightning-layout-item>
            </lightning-layout>
        </template>

    </lightning-card>
</template>

eventWithData.js: 在handleSelect中,使用find根据ID去进行匹配,匹配后便会获取到list中的指定的那条数据记录。下面的console中也弄了一个findIndex的写法。

/* eslint-disable no-console */
import { LightningElement, wire, track } from ‘lwc‘;
import getContactList from ‘@salesforce/apex/ContactController.getContactList‘;

export default class EventWithData extends LightningElement {
    @track selectedContact;

    @wire(getContactList) contacts;

    handleSelect(event) {
        const contactId = event.detail;
        /**
         * find方法定义如下: find(predicate: (this: void, value: number, index: number, obj: number[]) => value is number, thisArg?: any)
         * array.find方法用于通过某个指定的条件去获取满足条件的第一个的数据,找到满足条件的以后,后面的便不会在执行,如果遍历没有找到符合的则返回undefined.
         * 此函数不影响原有的array
         */
        this.selectedContact = this.contacts.data.find(
            contact => contact.Id === contactId
        );

        let datalist = [10,1,13,14];
        let result1 = datalist.findIndex(
            data => data > 20
        );
        console.log(result1);

    }
}

结果展示:

三.  some & every

我们有时候会有需求为判断当前的列表的内容是否满足某些条件,有一个满足内容则返回true,都不满足返回false;或者是全部满足返回true,有一个不满足就返回false。这个时候就要用到some & every了。 some用于列表的内容只要有一个item满足了条件则返回true,every为所有的都满足才返回true,这两个返回类型为布尔类型,不影响原有的list的值。在for循环中使用和在函数中使用写法可能多少有点区别,下面给一个demo用来展示写法。需求为我们将account表中的test__c(multi picklist)展示成列表样式来判断某个item是否选中,代码如下:

someEverySample.html:列表展示multi picklist的样式

<template>
    <table class="slds-table slds-table_cell-buffer slds-table_bordered">
        <thead>
            <tr class="slds-line-height_reset">
                <td>组件名称</td>
                <template if:true={resultList}>
                    <template for:each={resultList} for:item="result">
                        <th class="" scope="col" key={result.label}>
                            <div class="slds-truncate">{result.label}</div>
                        </th>
                    </template>
                </template>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>是否选中</td>
                <template if:true={resultList}>
                    <template for:each={resultList} for:item="result">
                        <td key={result.label}>
                            {result.isSelected}
                        </td>

                    </template>
                </template>
            </tr>

        </tbody>
    </table>
</template>

someEverySample.js: result list中有针对some / every的demo以及写法,在函数内写法和在for循环中写法多少有点区别,因为for循环里面写有一些限制。

/* eslint-disable no-console */
import { LightningElement,api,wire } from ‘lwc‘;
import { getRecord,getFieldValue } from ‘lightning/uiRecordApi‘;
import ACCOUNT_TEST_FIELD from ‘@salesforce/schema/Account.test__c‘;
import { getObjectInfo } from ‘lightning/uiObjectInfoApi‘;
import ACCOUNT_OBJECT from ‘@salesforce/schema/Account‘;
import {getPicklistValues} from ‘lightning/uiObjectInfoApi‘;

export default class SomeEverySample extends LightningElement {

    @api recordId;

    @wire(getRecord,{recordId:‘$recordId‘,fields:ACCOUNT_TEST_FIELD})
    wiredAccount;

    @wire(getObjectInfo, { objectApiName: ACCOUNT_OBJECT })
    accountInfo;

    @wire(getPicklistValues,{ recordTypeId: ‘$accountInfo.data.defaultRecordTypeId‘, fieldApiName: ACCOUNT_TEST_FIELD })
    testList;

    get resultList() {
        if(this.wiredAccount && this.wiredAccount.data && this.testList && this.testList.data && this.testList.data.values) {
            let testFieldValueStr = getFieldValue(this.wiredAccount.data,ACCOUNT_TEST_FIELD);
            let selectedTestValues = testFieldValueStr != null ? testFieldValueStr.split(‘;‘) : [];
            let testValues = this.testList.data.values;
            let results = [];
            let res = results.some((item,index) => item > 10 && index > 0);
            let resEvery = results.every((item,index) => item > 10 && index > 0);
            console.log(res);
            console.log(resEvery);
            for(let index in testValues) {

                if(selectedTestValues.some(function(item,itemIndex) {
                    console.log(itemIndex);
                    return item === testValues[index].value;

                }, this)) {
                    results.push({‘label‘:testValues[index].label,‘isSelected‘:true});
                } else {
                    results.push({‘label‘:testValues[index].label,‘isSelected‘:false});
                }

            }
            return results;
        }
        return [];
    }

}

效果展示:123/1234等值为我们Test__c表里面的picklist values,true/false为我们在这条数据中是否选择了相关的item。

四. reduce

reduce用来接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始合并,最终为一个值.所以我们使用reduce对列表处理最终会返回一个值,要么是布尔,要么是number等。reduce常用场景也可以查看篇中最上面的链接去详细查看。

/*
(method) Array<any>.reduce(callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue: any): any (+2 overloads)
        Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
        @param callbackfn — A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
        @param initialValue — If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
 */

我们对reduce有一个了解以后弄一个常用的demo来更好的消化。

reduceSample.html:展示多个输入框,点击button去触发一个事件处理

<template>
    <lightning-card title="LdsUpdateRecord" icon-name="standard:record">
        <div class="slds-m-around_medium">
            <template if:true={contact.data}>
                <lightning-input label="Id" disabled value={contact.data.Id}></lightning-input>
                <lightning-input label="First Name" value={contact.data.FirstName} data-field="FirstName" onchange={handleChange} class="slds-m-bottom_x-small"></lightning-input>
                <lightning-input label="Last Name" value={contact.data.LastName} data-field="LastName" onchange={handleChange} class="slds-m-bottom_x-small" required></lightning-input>
                <lightning-button label="Update Contact" variant="brand" onclick={updateContact} disabled={disabled}></lightning-button>
            </template>
            <template if:true={contact.error}>
                <!-- handle Apex error -->
            </template>
        </div>
    </lightning-card>
</template>

reduceSample.js:demo中是对lightning-input进行遍历,如果有没有满足check的,则报错,然后执行报错的提示信息,只有所有的都不报错了以后才执行validation 通过的逻辑。reportValidity以及checkValidity是lightning针对Input常用的很好的自带的方法,后期可能对Lightning input进行单独的博客讲解,感兴趣的可以自行查看这两个方法。我们通过reduce方法最后只返回一个true/false的值。

import { LightningElement, track, wire } from ‘lwc‘;
import { ShowToastEvent } from ‘lightning/platformShowToastEvent‘;

import getSingleContact from ‘@salesforce/apex/ContactController.getSingleContact‘;

export default class ReduceSample extends LightningElement {
    @track disabled = false;
    @track error;

    @wire(getSingleContact)
    contact;

    handleChange(event) {
         // Display field-level errors and disable button if a name field is empty.
        if (!event.target.value) {
            event.target.reportValidity();
            this.disabled = true;
        }
        else {
            this.disabled = false;
        }
    }

    updateContact() {
        let allInputList = Array.from(this.template.querySelectorAll(‘lightning-input‘));
        /*
        方法声明如下:
        (method) Array<any>.reduce(callbackfn: (previousValue: any, currentValue: any, currentIndex: number, array: any[]) => any, initialValue: any): any (+2 overloads)
        Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
        @param callbackfn — A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
        @param initialValue — If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
         */
        const allValid = allInputList.reduce((validSoFar, inputFields) => {
                inputFields.reportValidity();
                return validSoFar && inputFields.checkValidity();
            }, true);

        if (allValid) {
            //TODO success related operation
        } else {
            // The form is not valid
            this.dispatchEvent(
                new ShowToastEvent({
                    title: ‘Something is wrong‘,
                    message: ‘Check your input and try again.‘,
                    variant: ‘error‘
                })
             );
        }
    }
}

五. map & filter

map用来返回一个新数组,不影响原有的操作的list。这个新数组可以为这个list的每条数据针对某个条件处理以后的值,比如我们想要将一个list的里面的每一个值都乘以5然后返回一个新的数组,这个时候我们就可以使用map,只需要条件为对item * 5的操作即可。

filter用来使用指定的函数测试所有元素,并返回一个包含所有通过测试的元素的新数组,此方法不影响原有的list。

这两个基础的意思了解以后,来个demo更好的了解一下。

mapSample.html

<template>
    <lightning-input label="Category 1" type="checkbox" onchange={handleCheckboxChange}></lightning-input>
    <lightning-input label="Category 2" type="checkbox" onchange={handleCheckboxChange}></lightning-input>
</template>

mapSample.js: 点击checkbox以后获取选中的选项的label名称,通过filter获取到指定的想要数据,通过map获取到list的变形,及我们根据规则获取到的想要的数据。

/* eslint-disable no-console */
import { LightningElement } from ‘lwc‘;

export default class MapSample extends LightningElement {
    handleCheckboxChange() {
        const lightningInputList = Array.from(
            this.template.querySelectorAll(‘lightning-input‘));
        console.log(JSON.stringify(lightningInputList));
        const filters =  lightningInputList.filter(element => element.checked)
            .map(element => element.label);

        console.log(JSON.stringify(filters));
    }
}

总结:篇中都是lwc中针对list的常用的前端的使用方法,除了上述的方法以外还有其他的很多方法没有列出,小伙伴们自行查看。篇中有错误的地方欢迎指出,有不懂的欢迎留言。

原文地址:https://www.cnblogs.com/zero-zyq/p/12130254.html

时间: 2024-08-02 18:02:13

Salesforce LWC学习(十) 前端处理之 list 处理的相关文章

Salesforce LWC学习(八) Look Up组件实现

本篇参考https://www.salesforcelwc.in/2019/10/lookup-in-lwc.html,感谢前人种树. 我们做lightning的时候经常会遇到Look up 或者MD字段在页面搜索展示的需求,在标准的页面很常见,而且很好看.但是很遗憾的是在自定义组件中还没有现成的标准组件去搞定.下面介绍两种方式去实现展示lookup / MD字段的组件样式.  一.  record-edit-form搭配 lightning-input-field 曲线救国 标准功能也不是10

对比深度学习十大框架:TensorFlow 并非最好?

http://www.oschina.net/news/80593/deep-learning-frameworks-a-review-before-finishing-2016 TensorFlow 链接:https://www.tensorflow.org/ 对于那些听说过深度学习但还没有太过专门深入的人来说,TensorFlow 是他们最喜欢的深度学习框架,但在这里我要澄清一些事实. 在 TensorFlow 的官网上,它被定义为「一个用于机器智能的开源软件库」,但我觉得应该这么定义:Te

Oracle学习(十四):管理用户安全

--用户(user) SQL> --创建名叫 grace 密码是password 的用户,新用户没有任何权限 SQL> create user grace identified by password; 验证用户: 密码验证方式(用户名/密码) 外部验证方式(主机认证,即通过登陆的用户名) 全局验证方式(其他方式:生物认证方式.token方式) 优先级顺序:外部验证>密码验证 --权限(privilege) 用户权限有两种: System:允许用户执行对于数据库的特定行为,例如:创建表.

Oracle学习(十五):分布式数据库

--分布式数据库的独立性:分布数据的独立性指用户不必关心数据如何分割和存储,只需关心他需要什么数据. --本地操作 SQL> sqlplus scott/tiger --远程操作 SQL> sqlplus scott/[email protected]:1521/orcl --分布式操作 SQL> --创建数据库链路l2(需要权限): SQL> --remoteorcl服务命名(在net manager里配置):配置跟远程服务器的数据库的连接协议.主机名(ip地址).端口号等 SQ

Oracle学习(十):视图,索引,序列号,同义词

1.知识点:可以对照下面的录屏进行阅读 视图,序列,索引,同义词 SQL> --视图:虚表 SQL> --视图的优点:简化复杂查询,限制数据访问(银行用的多),提供数据的相互独立,同样的数据可以有不同的显示方式 SQL> --第一个视图: 员工号 姓名 月薪 年薪 SQL> create view view1 2 as 3 select empno,ename,sal,sal*12 annlsal from emp; SQL> --如果显示没有权限,则需要授权,见下图1-1

学习web前端开发感想

1.学习一个技术,不是一看见源代码就是copy,而是仔细阅读后,找到自己想要的,并且自己写出来,自己理解了,下次遇到同样的问题,自己才能解决. 2.在电脑上学习的过程中,我总是先建立一个文本文档,这样便于记录,然后再进行分类到笔记本中... 3.把你看到的每个网页用大脑生成html代码和css布局. 把你看到的每个动画和交互用大脑生成javaScript. 4.一定要养成做好笔记的习惯.并且要学会做笔记. 5.页面中中所有的东西都要放在一个标签里面.否则不好控制. 6.自己的知识库在开始学习的时

独家分享——大牛教你如何学习Web前端开发

2014-12-18 14:35:42   引语 自从2008年接触网站开发以来到现在已经有六个年头了,今天偶然整理电脑资料看到当时为参加系里面一个比赛而做的第一个网站时,勾起了在这网站开发道路上的一串串回忆,成功与喜悦.烦恼与纠结都历历在目,感慨颇多.在此与大家分享,希望对初学Web前端的各位童鞋来说有所帮助.欢迎各位吐槽.拍砖. 先从大家学习上的一个误区开始谈起. Web前端的学习误区 网页制作是计算机专业同学在大学期间都会接触到的一门课程,而学习网页制作所用的第一个集成开发环境(IDE)想

CSS基础学习十五:盒子模型补充之外边距合并

今天继续接着CSS盒子模型补充,CSS基础学习十三:盒子模型和CSS基础学习十四:盒子模型补充之display属 性设置都是介绍了盒子模型中的内容概括.开始今天的主题:外边距合并. 外边距合并指的是,当两个垂直外边距相遇时,它们将形成一个外边距.合并后的外边距的高度等于两个发生合 并的外边距的高度中的较大者. (1)外边距合并 外边距合并叠加是一个相当简单的概念.但是,在实践中对网页进行布局时,它会造成许多混淆.简单地说,外 边距合并指的是,当两个垂直外边距相遇时,它们将形成一个外边距.合并后的

为什么学习web前端开发?

本文主要分析web开发的相关方向及技术,为想投入web开发的同学提供下参考. 什么是WEB开发 说到WEB开发就不得不提两种架构模式,B/S架构和C/S架构. 互联网发展初期,大多数系统都是C/S架构,C代表客户端,S代表服务器,常见的软件,比如QQ(WEB版的不算),都是采用这种架构模式.这种架构模式通过将任务合理分配到Client端和Server端,降低了系统的通讯开销,可以充分利用两端硬件环境的优势.B/S架构(浏览器/服务器)是随着Internet技术的兴起而出现的,它是C/S架构的改进