使用Charts Js在Lightning Web组件中将数据从父级传递到子级

时间:2019-03-05 18:48:38

标签: javascript salesforce salesforce-lightning

我最近在Lightning Web组件中使用Charts JS遇到问题。我想分享给遇到问题的人的解决方案

如何在父组件上更新子组件中的数据更改时对其进行手动处理。这适用于所有内容,但我试图更新它们显示的Chartsjs示例。

2 个答案:

答案 0 :(得分:1)

这是我想出的解决方案。

父控制器具有以下嵌套功能

@wire(getRecord, { recordId: '$recordId', fields: CONTACT_FIELDS })
wireContact({ error, data }) {
    if (data) {
        console.log('getRecord Data', JSON.stringify(data))
        this.contact = data;
        getAllDateRecords({ contactId: this.recordId })
            .then(result => {
                this.allDateRecords = result;
                this.chartReady = true;
            })
            .catch(err => console.log(JSON.stringify(err)));
    } else if (error) {
        console.error('error', error)
        this.contact = undefined;
    }

}

父组件具有c-debt-chart组件,并从所有日期记录中删除其接收数据:

<template>
<div class="slds-page-header__row slds-accordion__content">
                <div class="c-container w-100">
                    <lightning-layout horizontal-align="space">
                        <lightning-layout-item padding="around-small">
                            <template if:true={chartReady}>
                                <c-debt-chart all-date-records={allDateRecords}></c-debt-chart>
                            </template>
                        </lightning-layout-item>
                    </lightning-layout>
                </div>
            </div>
<template>

问题在于Salesforce上的示例未显示如何更新图表js中的数据。这是我使用Getter和Setters找到的解决方案

儿童部分债务图表

<template>
    <lightning-card title="Debt Overview" icon-name="standard:currency">
        <div class="slds-m-around_medium">
            <canvas class="donut" lwc:dom="manual"></canvas>
        </div>
    </lightning-card>
</template>

债务图表控制器

每次,变量allDateRecords都会在父级更改。它将触发孩子使用getter setter方法进行更新。这样,在setter方法上将触发seperateDateObject函数,该函数会执行一些逻辑来更新图表。

@api
get allDateRecords() {
    return this._allDateRecords;
}

set allDateRecords(value) {
    this._allDateRecords = value;
    this.separateDateObject();
}

答案 1 :(得分:0)

当您的逻辑只依赖一个 api 属性时,上述解决方案有效

如果您有多个可以同时更改的 api 属性,这些属性也应该共同用于决策,您可能需要使用 renderCallback() 来执行逻辑。

    @api
    get prop1() {
        return this._prop1;
    }
    set prop1(value) {
        this._prop1= value;
        this.somelogic();    //needs to be called in every dependent set prop
    }
    
    
    @api
    get prop2() {
        return this._prop2;
    }
    set prop2(value) {
        this._prop2= value;
        this.somelogic();   //needs to be called in every dependent set prop
    }

    somelogic(){
        this.showsomething = this._prop1 && this._prop2; //dependent logic
    }

在每个 setter 中调用 somelogin 也可能导致在设置属性期间出现突然的 UI 行为。

改为

renderedCallback(){
    this.somelogic();    //can even execute code conditionally
}

如果未触发渲染回调,则通过使用模板中的 api 属性和 if:true 强制渲染,有助于实现故障安全代码

<template if:true={_prop1}>
    <template if:true={_prop2}>
         <!--place dependant html here-->
    <template>
<template>