本篇参考:
https://developer.salesforce.com/docs/platform/lwc/guide/reference-graphql.html
https://developer.salesforce.com/docs/platform/lwc/guide/reference-refreshgraphql.html
https://developer.salesforce.com/docs/platform/graphql/guide/graphql-wire-lwc.html
https://developer.salesforce.com/docs/component-library/bundle/lightning-record-picker/documentation
**背景:**想象一下我们以前做项目如果需要一个搜索功能的时候,比如搜索Account列表数据,查询条件可以基于Owner或者某个自定义的lookup字段进行查询时,我们通常要如何设计?
- 创建custom lookup component来支持;
- 通过 lightning-record-edit-form搭配 lightning-input-field,input-field字段绑定着lookup字段来实现。
先不评论方案的好坏,这两种都需要花费不少的时间以及考虑不同的点,可扩展性达不到保证。 除此以外,有时还需要考虑其他的问题,比如通过哪个字段进行搜索,显示哪个字段,UI效果稳定性等等。现在我们就不用有这样的顾虑了,因为 lightning-record-picker来了。
一. lightning-record-picker
lightning-record-picker组件允许你基于输入的内容返回所对应的数据列表并且直接进行渲染,使用 GraphQL wire adapter来进行数据搜索,数据显示以及数据选择一条以后的信息获取。 至于GraphQL是什么,我们后续再说。
我们先看一下 lightning-record-picker的最简单的一个例子,只需要html的代码,js不需要任何内容。
<template>
<lightning-record-picker
label="Accounts"
placeholder="Search Accounts..."
object-api-name="Account">
</lightning-record-picker>
</template>
**效果显示:**这个UI效果,如果做过 custom lookup组件的小伙伴应该很熟悉,除🔍的位置不同以外,其他的效果基本一致。
lightning-record-picker除这个最基础的以外,还支持哪些扩展呢?
**1. Filter:**就像lookup字段支持 Lookup Filter一样,我们在使用搜索功能时,有时希望加一些前置的过滤条件,从而初始时就过滤掉我们不需要的数据。lightning-record-picker也支持filter功能而且用法很简单。我们对上面的代码进行一下改造
recordPickerSample.html:增加了filter属性
<template>
<lightning-record-picker
label="Accounts"
placeholder="Search Accounts..."filter={filter}object-api-name="Account">
</lightning-record-picker>
</template>
recordPickerSample.js: 增加了filter变量,我们可以看到结构体主要两部分:
- criteria: 用于指定我们的过滤的条件,包含三部分,并且这三部分都是必填内容:
- fieldPath: object api name
- operator: 操作符
- value: 过滤字段的值
- filterLogic:可选项,如果不包含这个值,默认所有的条件是AND,如果需要自定义,则添加这个值。
注:官方文档中这里的代码写的是错误的,如果直接复制粘贴无法运行,因为filterLogic位置不正确。
import { LightningElement, track, wire } from 'lwc';
export default class recordPickerSample extends LightningElement {
filter = {
criteria: [
{
fieldPath: 'AccountSource',
operator: 'ne',
value: 'Other'
},
{
fieldPath: 'Type',
operator: 'eq',
value: 'Prospect'
}
],
filterLogic: '1 OR 2',
}
}
上面的代码主要实现的是搜索记录时,要求记录还需要满足 AccountSource不等于Other或者Type等于Prospect。除此以外,我们看到operator的值有点怪,ne和eq,这些代表什么呢?
|----------|----------------------------------|
| Function | Description |
| eq | Equals。 |
| ne | Not Equals. |
| lt | less than。 |
| gt | great than。 |
| lte | Less than or equal |
| gte | Greater than or equal |
| like | 和soql中的用法相同 |
| in | 和soql中的IN用法相同 |
| nin | 和soql中的Not IN用法相同 |
| inq | 元素在一个query集中,和soql的 in子查询相同 |
| ninq | 元素不在一个query集中,和soql的not in 子查询相同 |
| includes | multi picklist包含某个值 |
| excludes | multi picklist不包含某个值 |
2. Display: 默认我们会显示搜索的Name字段的值,如果我们需要显示其他的值,我们可以通过display-info属性来实现。目前additional fields 只支持1个,即列表最多只允许显示两个字段。我们将上面的代码进行增强。
recordPickerSample.html:增加 display-info属性
<template>
<lightning-record-picker
label="Accounts"
placeholder="Search Accounts..."
filter={filter}
display-info={displayInfo}
object-api-name="Account">
</lightning-record-picker>
</template>
recordPickerSample.js:声明变量,变量使用 additionalFields。
import { LightningElement, track, wire } from 'lwc';
export default class recordPickerSample extends LightningElement {
filter = {
criteria: [
{
fieldPath: 'AccountSource',
operator: 'ne',
value: 'Other'
},
{
fieldPath: 'Type',
operator: 'eq',
value: 'Prospect'
}
],
filterLogic: '1 OR 2',
}
displayInfo = {
additionalFields: ['Owner.Name']
}
}
效果显示:
3. Matching Info: 默认我们是基于Name字段进行搜索,但是有时我们还需要其他的字段进行搜索,比如搜索Account Name时,我们还需要基于某个自定义字段进行协同搜索。这里我们就可以使用matching info,我们看一下下面的demo。
recordPickerSample.html: 通过 matching-info属性来赋值。
<template>
<lightning-record-picker
label="Accounts"
placeholder="Search Accounts..."
filter={filter}
display-info={displayInfo}
matching-info={matchingInfo}
object-api-name="Account">
</lightning-record-picker>
</template>
recordPickerSample.js: matchingInfo属性可以设置两个信息: primaryField以及additionalFields参数。尽管additionalFields参数传递是数组,但是目前仍然最多也只允许1个值。
import { LightningElement, track, wire } from 'lwc';
export default class recordPickerSample extends LightningElement {
filter = {
criteria: [
{
fieldPath: 'AccountSource',
operator: 'ne',
value: 'Other'
},
{
fieldPath: 'Type',
operator: 'eq',
value: 'Prospect'
}
],
filterLogic: '1 OR 2',
}
displayInfo = {
additionalFields: ['Phone']
}
matchingInfo = {
primaryField: { fieldPath: 'Name' },
additionalFields: [ { fieldPath: 'Phone' } ]
}
}
**效果显示:**demo中通过Phone的信息也可以搜索出想要的信息
**4. 事件:**组件封装了几个标准行为的事件,其他的小伙伴自行查看,这里只介绍 change事件,handler用于返回所选中的recordId信息。demo会和下面的一起介绍。
二. lightning-record-picker实现WhatId等多选择的效果
既然record-picker只需要传递object信息就可以做出最简单的效果,我们的另外一个好的应用就是作出whatId以及whoId的效果。以前我们做这种自定义的组件会耗时耗力,现在就比较容易了。我们直接看代码。
dynamicRecordPickerSample.html
<template>
<div class="slds-form-element">
<label class="slds-form-element__label">Select a record</label>
<div class="slds-form-element__control slds-combobox-group">
<lightning-combobox
label="Select Object"
variant="label-hidden"
options={objNametList}
value={selectedObject}
onchange={handleTargetSelection}
>
</lightning-combobox>
<lightning-record-picker
object-api-name={selectedObject}
placeholder="Search..."
label="Select a record"
variant="label-hidden"
onchange={handleRecordSelect}
class="slds-size_full slds-combobox-addon_end"
>
</lightning-record-picker>
</div>
</div>
</template>
dynamicRecordPickerSample.js
import { LightningElement } from 'lwc';
export default class dynamicRecordPickerSample extends LightningElement {
objNametList = [
{label: 'Account',value: 'Account'},
{label: 'Contact',value: 'Contact'},
{label: 'Opportunity',value: 'Opportunity'},
{label: 'Case',value: 'Case'}
];
selectedObject = 'Account';
currentSelectedRecordId;
handleObjectChange(event) {
this.selectedObject = event.target.value;
}
handleRecordSelect(event) {
this.currentSelectedRecordId = event.detail.recordId;
console.log('*** this.currentSelectedRecordId : ' + this.currentSelectedRecordId);
}
}
效果显示:
总结: 篇中主要介绍了lightning-record-picker的使用,record-picker基于GraphQL的wire adapter来实现,后续的篇章中有机会也会讲一下GraphQL Wire Adapter等相关知识。官方文档中有一些错误,导致复制粘贴无法运行,不要怀疑自己,修改以后重新尝试。篇中有错误地方欢迎指出,有不懂欢迎留言。