我有一个充当ToolBox的LWC :用户从ToolBelt中选择一个工具,然后用该工具的业务逻辑填充一个WorkArea。
涉及的组成部分:
父级:Wrapper.js
儿童1:ToolBelt.js
儿童2:WorkArea.js
():首先,Wrapper.js将ToolSelection处理程序传递给ToolBelt.js。在select上,事件从ToolBelt.js发出到Wrapper.js,其中selectedTool变量正在更新。
():selectedTool在父级中使用@api修饰,在子层中使用@selectedTool,并且在父级中成功地更新了值。但是它没有在子组件中重新命名。
Parent.js:
import { LightningElement, api } from 'lwc';
export default class Toolbox extends LightningElement {
@api selectedTool
@api tools = [redacted]
toolSelectionHandler(event){
let updatedTools
let selectedTool;
const id = event.detail.id
const action = event.detail.action
if( action === 'unselect'){
updatedTools = this.tools.map( (tool) => {
tool.selected = false
return tool
})
this.selectedTool = null
} else{
updatedTools = this.tools.map( (tool) => {
if(tool.id === id){
tool.selected = true
selectedTool = tool
}
else {
tool.selected = false
}
return tool
})
this.selectedTool = selectedTool
}
this.tools = updatedTools
}
}
Parent.html:
<template>
<div class="slds-grid slds-wrap slds-grid--pull-padded">
<div class="slds-p-horizontal--small slds-size--1-of-2 slds-medium-size--1-of-6 slds-large-size--4-of-12" >
<c-toolbelt
tools={tools}
ontoolselected={toolSelectionHandler}
></c-toolbelt>
</div>
<div class="slds-p-horizontal--small slds-size--1-of-2 slds-medium-size--5-of-6 slds-large-size--8-of-12">
<c-work-area
selected-tool={selectedTool}
>
</c-work-area>
</div>
</div>
省略了Toolbelt.js和Toolbelt.html,因为选择处理程序正在按预期工作。
WorkArea.js:
import { LightningElement, track } from 'lwc';
export default class WorkArea extends LightningElement {
@track selectedTool
@track isLoading = false
get tool1(){
let matchBool
if(!this.selectedTool){
matchBool = false
} else {
if (this.selectedTool.title = 'tool1') {
matchBool = true
}
}
return matchBool;
}
get tool2(){
let matchBool
if(!this.selectedTool){
matchBool = false
} else {
if (this.selectedTool.title = 'tool2') {
matchBool = true
}
}
return matchBool;
}
get tool3(){
let matchBool
if(!this.selectedTool){
matchBool = false
} else {
if (this.selectedTool.title = 'tool3') {
matchBool = true
}
}
return matchBool;
}
spinnerHandler(){
this.isLoading = !this.isLoading
}
}
WorkArea.html:
<template>
<div class="work-area">
<div if:true={toolOne} class="tool-detail-area selected">
<c-tool-one
onspinnerhandler={spinnerHandler} >
</c-tool-one>
</div>
<div if:true={toolTwo} class="tool-detail-area selected">
<c-tool-two
onspinnerhandler={spinnerHandler} >
</c-tool-two>
</div>
<div if:true={toolThree} class="tool-detail-area selected">
<c-tool-three
onspinnerhandler={spinnerHandler} >
</c-tool-three>
</div>
<div if:false={selectedTool} class="tool-detail-area default">
<c-no-tool-display></c-no-tool-display>
</div>
<div if:true={isLoading}>
<c-loading-spinner></c-loading-spinner>
</div>
</div>
我见过一些关于LWC子组件的帖子没有注册对父组件所做的更改,但是它们中的大多数都是直接的父>子关系。因为事件不是从孩子身上发出的。我还没有见过任何子程序修改父级状态的地方,并且跟踪了兄弟姐妹中的变量没有重新呈现。
任何技术上或概念上的帮助都将不胜感激。
发布于 2022-10-03 22:41:41
(从评论/扩充中改划)
为什么WorkArea的selectTool只是@track而不是@api?你有办法把任何东西传给那个孩子吗?我有点惊讶。如果它是一个原语(字符串、数字等),那么您甚至不需要跟踪。
它必须是@api才能成为组件的公共接口的一部分,所以我认为您设置父级的值没有任何效果。这个变量是子组件的私事,很好的尝试父母。
在父级事件处理程序中,尝试重新构建变量this.selectedTool = JSON.parse(JSON.stringify(this.selectedTool));
,并查看它是否有帮助
这是一个复杂和臭味的货物邪教编程。我不知道。重新构建变量(对象或对象数组)有时有助于@track / @api实现值更改并正确传播。在网络往返中有一些缓存/保存。
它不应该需要,@track
应该是足够的..。但是人们与它斗争,你可以在一些博客上看到窍门,或者
JSON.parse“舞蹈”是可以的,但是你当然会失去你可能附加到对象上的任何函数,日期会变成字符串.在JS控制台中调试某些东西时使用它是很常见的,而且您对所有的代理对象都很生气。数组扩展操作符也可以为@track/@api提供一个提示,可能也可以更快地执行。
另一个地方,它帮助是当你需要修改什么是从Apex发送。通常,该对象是只读的,您需要JSON.parse或扩展来复制(?)。例如,使用<lightning-tree-grid>
处理来自服务器端的任何数据,祝您好运。它要求子节点为_children
,但Apex不使用以下划线开头的变量名进行编译。所以你需要得到你的数据,然后用JS:https://salesforce.stackexchange.com/a/235214/799来修饰它。
https://stackoverflow.com/questions/73912261
复制相似问题