LWC 父子组件通信问题

huangapple go评论145阅读模式
英文:

LWC Parent-to-Child communication issue

问题

我正在使用两个LWC组件。两者之间有一个父子关系。在我的parent.js中,我使用了一个包含对象数组的Apex类:

Parent.js:

// 导入...

export default class MyParent.js extends LightningElement {

currentUserProjects;

@wire(getProjectsForYear, { consultantId: '$consultantId', year: 2023 })

wiredProjectIdsForYear({ data, error }) {

    if (data) {

        this.currentUserProjects = data;

    } else if (error) {

        this.createErrorMessage(error.body.message);

    }

}
 

`this.currentUserProjects` 检索到以下对象列表:

    [
        {
            "Name": "Test Session 1",
            "test__Client__c": "Test Session 1",
            "test__Start_Time__c": 32400000,
            "test__End_Time__c": 36000000,
            "test__Start_Date__c": "2023-03-08",
            "test__End_Date__c": "2023-03-08",
            "test__ID__c": "ID 215119",
            "Virtual_Session_Link__c": "https://bts.zoom.us/",
            "Id": "a0g59000000f21AAA"
        }
    ]

在我的parent.html中:


```

在我的child.js中:

// 导入...

export default class MyChildComponent extends LightningElement {

    @api projects;

 

    connectedCallback() {

        console.log(this.projects);

    }

}

问题在于在我的child.js中,console.log(this.projects); 在控制台中返回undefined,而在parent.js中,console.log(this.currentUserProjects); 能够正确返回数据。

我尝试定义另一个随机变量并在child.js中打印它,它可以正常工作,所以我猜测this.currentUserProjects可能有问题。

希望有人能帮助解决这个问题。


<details>
<summary>英文:</summary>

I&#39;m working with two lwc components. Both have a relationship parent-child. In my parent.js I wire an Apex class which contains an objects array:

Parent.js:

// imports...

export default class MyParent.js extends LightningElement {

currentUserProjects;

@wire(getProjectsForYear, { consultantId: &#39;$consultantId&#39;, year: 2023 })

wiredProjectIdsForYear({ data, error }) {

    if (data) {

        this.currentUserProjects = data;

    } else if (error) {

        this.createErrorMessage(error.body.message);

    }

}
 

`this.currentUserProjects` retrieves the following object list:

    [
        {
            &quot;Name&quot;: &quot;Test Session 1&quot;,
            &quot;test__Client__c&quot;: &quot;Test Session 1&quot;,
            &quot;test__Start_Time__c&quot;: 32400000,
            &quot;test__End_Time__c&quot;: 36000000,
            &quot;test__Start_Date__c&quot;: &quot;2023-03-08&quot;,
            &quot;test__End_Date__c&quot;: &quot;2023-03-08&quot;,
            &quot;test__ID__c&quot;: &quot;ID 215119&quot;,
            &quot;Virtual_Session_Link__c&quot;: &quot;https://bts.zoom.us/&quot;,
            &quot;Id&quot;: &quot;a0g59000000f21AAA&quot;
        }
    ]

In my parent.html: 

<template>

&lt;c-my-child-component projects={currentUserProjects}&gt;&lt;/c-my-child-component&gt;

</template>

 

In my child.js:

// imports..

export default class MyChildComponent extends LightningElement {

@api projects;



connectedCallback() {

    console.log(this.projects);

}

}


The problem is that `console.log(this.projects);` at my child.js retrieves me an &#39;undefined&#39; in the console while `console.log(this.currentUserProjects);` at parent.js retrieves me the data correctly. 

 

I tried defining another random variable and printing it at my child.js and works, so I guess something is wrong with my `this.currentUserProjects`. 

 

Hope someone could help with this.

</details>


# 答案1
**得分**: 0

你可以尝试使用`@track`装饰器,就像这样:`@track currentUserProjects`。

如果这不起作用,那么尝试在子组件中使用以下代码:

```js
// 导入...

export default class MyChildComponent extends LightningElement {

    _projects = [];

    // 我们添加了一个getter和setter
    @api
    get projects() {
        return this._projects;
    }

    set projects(newValue) {
        // 每次projects接收到新值时都会执行此操作
        this._projects = newValue;
    }

    renderedCallback() {

        if(this.projectsExist) {
            console.log('我们有项目!');
        }

    }

    get projectsExist() {
        return this.projects.length > 0;
    }

}

此外,在你的子组件的HTML中,如果你正在使用for:each来渲染projects,你可以尝试类似以下的代码:

<template if:true={projectsExist} for:each={projects} for:item="project">

    <p>{project.Name}</p>

</template>
英文:

You could try the @track decorator like @track currentUserProjects.

If that doesn't work, then try this on the child component:

// imports..

export default class MyChildComponent extends LightningElement {

    _projects = [];

    // We add a getter and setter
    @api 
    get projects() {
        return this._projects;
    }

    set projects(newValue) {
        // This is going to be executed every time 
        // projects receive a new value
        this._projects = newValue;
    }

    renderedCallback() {

        if(this.projectsExist) {
            console.log(&#39;We have projects!&#39;)
        }

    }

    get projectsExist() {
        return this.projects.length &gt; 0;
    }

}

Also, in the HTML of your child component, you could try something like this if you are rendering the projects on a for:each

&lt;template if:true={projectsExist} for:each={projects} for:item=&quot;project&quot;&gt;

    &lt;p&gt;{project.Name}&lt;/p&gt;

&lt;/template&gt;

答案2

得分: 0

解决方案: 问题是子组件在我的父组件 wire 返回数据之前被渲染,因此我做了以下操作:

Parent.html:

<template>
  <template if:true={loadingcomplete}>
      <c-my-child-component projects={currentUserProjects}></c-my-child-component>
  </template>
</template>

Parent.js:

// imports...
export default class MyParent.js extends LightningElement {
    currentUserProjects;
    loadingcomplete = false;

    @wire(getProjectsForYear, { consultantId: '$consultantId', year: 2023 })
    wiredProjectIdsForYear({ data, error }) {
        if (data) {
            this.currentUserProjects = data;
            this.loadingcomplete = true;
        } else if (error) {
            this.createErrorMessage(error.body.message);
        }
    }
}

在我的 child.js 中的 console.log 打印了一个 Proxy {},所以我对数据进行了解析:

connectedCallback() {
     const accounts = JSON.parse(JSON.stringify(this.projects));
     console.log(accounts);
}

现在信息在我的 child.js 中被正确打印出来。 LWC 父子组件通信问题
希望这有所帮助!

英文:

SOLUTION: The problem was the child component was being rendered before my parent wire has returned the data, so I did the following:

Parent.html:

&lt;template&gt;
  &lt;template if:true={loadingcomplete}&gt;
      &lt;c-my-child-component projects={currentUserProjects}&gt;&lt;/c-my-child-component&gt;
  &lt;/template&gt;
&lt;/template&gt;

Parent.js:

// imports...
export default class MyParent.js extends LightningElement {
    currentUserProjects;
    loadingcomplete = false;

    @wire(getProjectsForYear, { consultantId: &#39;$consultantId&#39;, year: 2023 })
    wiredProjectIdsForYear({ data, error }) {
        if (data) {
            this.currentUserProjects = data;
            this.loadingcomplete = true;
        } else if (error) {
            this.createErrorMessage(error.body.message);
        }
    }
}

The console.log in my child.js printed a me a Proxy {} so I did a parse to my data:

connectedCallback() {
     const accounts = JSON.parse(JSON.stringify(this.projects));
     console.log(accounts);
}

Now the information is been printed in my child.js correctly. LWC 父子组件通信问题
Hope this helps!

huangapple
  • 本文由 发表于 2023年3月9日 17:11:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75682495.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定