英文:
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中:
<c-my-child-component projects={currentUserProjects}></c-my-child-component>
```
在我的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'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: '$consultantId', 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:
[
{
"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"
}
]
In my parent.html:
<template>
<c-my-child-component projects={currentUserProjects}></c-my-child-component>
</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 'undefined' 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('We have projects!')
}
}
get projectsExist() {
return this.projects.length > 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
<template if:true={projectsExist} for:each={projects} for:item="project">
<p>{project.Name}</p>
</template>
答案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 中被正确打印出来。
希望这有所帮助!
英文:
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:
<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);
}
}
}
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.
Hope this helps!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论