本篇参考:https://developer.salesforce.com/docs/component-library/bundle/lightning-datatable
背景:我们有时会有这种类似的需求,显示Account列表,Account列除了需要显示Account信息,还需要显示其他的内容,比如当前Account有多少Opportunity,有多少Contact数量。点击数量信息,可以显示详细的信息。 这种需求就需要datatable的某个单元格允许点击,点击以后进行某些逻辑,比如popup。因为标准的datatable无法实现功能,仅支持 onrowaction,所以我们继承LightningDatatable来自定义。
步骤如下:
1. 继承 LightningDatatable,创建template;
2. template中通过a标签,添加 onclick事件;
3. 针对onclick的handler,通过事件/广播方式传递给上层组件,从而上层事件来处理。(dispatchEvent测试以后发现不可用,所以demo中以message channel作为最终的呈现)
具体实施
filterChange.messageChannel-meta.xml: 设置message channel以及创建需要的变量,不同的需求有不同的变量,可以基于自己的需求来看。
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8"?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
<isExposed>true</isExposed>
<lightningMessageFields>
<description>Record Id</description>
<fieldName>dataId</fieldName>
</lightningMessageFields>
<lightningMessageFields>
<description>Record Type</description>
<fieldName>dataType</fieldName>
</lightningMessageFields>
<masterLabel>Filters Change Message Channel</masterLabel>
</LightningMessageChannel>
datatableWithClick.js: 用于继承LightningDatatable,设置自定义type:clickrow,template通过 onclickRow.html来操作。
代码语言:javascript复制import { LightningElement, track, wire } from 'lwc';
import LightningDatatable from 'lightning/datatable';
import onclickRow from './onclickRow.html';
export default class datatableWithClick extends LightningDatatable {
static customTypes = {
clickrow: {
template: onclickRow
}
};
}
onclickRow.html: 和datatableWithClick在同一个目录下,UI通过datatable-click-template来渲染,并且将参数值传递给param
代码语言:javascript复制<template>
<c-datatable-click-template
param={value}
>
</c-datatable-click-template>
</template>
datatableClickTemplate.html:a标签显示内容,然后设置 onclick事件
代码语言:javascript复制<template>
<a onclick={handleClickAction}>{label}</a>
</template>
datatableClickTemplate.js: 这里通过传递的value通过指定的格式来拆分,我们这里通过分号,实际可以基于自己的需求来弄。当点击以后,通过message channel发布事件
代码语言:javascript复制import { LightningElement, track, wire,api } from 'lwc';
import { publish, MessageContext } from 'lightning/messageService';
import FILTERSCHANGEMC from '@salesforce/messageChannel/filterChange__c';
export default class datatableClickTemplate extends LightningElement {
@wire(MessageContext)
messageContext;
@track label;
@track recordId;
@track type;
@api set param(value) {
console.log(value);
if(value && value.includes(';')) {
this.label = value.split(';')[0];
this.recordId = value.split(';')[1];
this.type = value.split(';')[2];
}
}
get param() {
return label;
}
handleClickAction(event) {
const filters = {
dataId: this.recordId,
dataType: this.type
};
publish(this.messageContext, FILTERSCHANGEMC, filters);
}
}
datatableSample.html: 调用 datatableWithClick组件
代码语言:javascript复制<template>
<c-datatable-with-click
data={data}
columns={columns}
key-field="id">
</c-datatable-with-click>
</template>
datatableSample.js: 设置初始值以及订阅发布的广播,订阅后执行handleFilterChange方法。
代码语言:javascript复制import { LightningElement,wire } from 'lwc';
import {
subscribe,
unsubscribe,
MessageContext
} from 'lightning/messageService';
import FILTERSCHANGEMC from '@salesforce/messageChannel/filterChange__c';
const columns = [
{label: 'Account name', fieldName: 'accountName', type: 'text'},
{
type: "clickrow",
fieldName: "numberOfOppty",
label: "Opportunity Count"
}
];
const data = [{
id: 'a',
accountName: 'Cloudhub',
numberOfOppty: '2;a;testRecordType'
},
{
id: 'b',
accountName: 'Quip',
numberOfOppty: '5;b;testOtherRT'
}];
export default class datatableSample extends LightningElement {
data = data;
columns = columns;
@wire(MessageContext)
messageContext;
connectedCallback() {
this.subscription = subscribe(
this.messageContext,
FILTERSCHANGEMC,
(message) => {
this.handleFilterChange(message);
}
);
}
disconnectedCallback() {
unsubscribe(this.subscription);
this.subscription = null;
}
handleFilterChange(filters) {
console.log('execute');
console.log(filters.dataId);
console.log(filters.dataType);
}
}
效果展示:
系统渲染的元素如下图所示,demo中使用的message channel,如果使用dispatchEvent,即使设置了bubble等于true, datatable-sample仍然无法handle,没有进行深入研究。
总结:篇中通过继承LightningDatatable实现了cell click的效果从而进行了更好的扩展。篇中有错误地方欢迎指出,有不懂欢迎留言。