我正在制作一个WordPress Gutenberg block,它有以下属性:
attributes: {
panels: {
type: "array",
default: [{
id: uuid(),
h2: "",
h3: "",
backgroundImage: "",
highlightText: "",
featureList: [""],
buttonText: "",
buttonUrl: "",
buttonColor: ""
}
}
}
可以看到,它是一个对象数组(panels[])。我遇到的问题是:当有2个或更多的面板,我开始输入到一个面板(h2,例如)所有其他面板消失。
下面是返回的JSX:return (
<div {...blockProps}>
<h2 className="tpp-heading">Tariff Product Panel</h2>
{props.attributes.panels.map((panel, panelIndex) => {
return (
<div className="tpp-product" id={panel.id}>
<h2 className="tpp-sub-heading">Product {panelIndex + 1}</h2>
<Button
onClick={() => removePanel(panelIndex)}
className="tpp-remove-panel"
title="Delete Panel">
<Icon
icon={
"remove"
}
/>
</Button>
<Flex>
<FlexBlock className="tpp-attribute">
<TextControl
value={panel.h2}
label="Heading"
onChange={(value) => updateAttribute(panelIndex, value, "h2", panel.id)}
/>
</FlexBlock>
<FlexBlock>
<TextControl
value={panel.h3}
label="Sub Heading"
onChange={(value) => updateAttribute(panelIndex, value, "h3", panel.id)}
/>
</FlexBlock>
</Flex>
<Flex>
<FlexBlock className="tpp-attribute">
<TextControl
value={panel.backgroundImage}
label="Background Image"
onChange={(value) => updateAttribute(panelIndex, value, "backgroundImage", panel.id)}
/>
</FlexBlock>
<FlexBlock>
<TextControl
value={panel.highlightText}
label="Highlight Text (if filled in, panel will have highlight)"
onChange={(value) => updateAttribute(panelIndex, value, "highlightText", panel.id)}
/>
</FlexBlock>
</Flex>
<Flex>
<FlexBlock className="tpp-attribute">
<TextControl
value={panel.buttonText}
label="Button Text"
onChange={(value) => updateAttribute(panelIndex, value, "buttonText", panel.id)}
/>
</FlexBlock>
<FlexBlock>
<SelectControl
label="Button Color"
value={panel.buttonColor}
options={[
{ label: 'Default', value: 'default' },
{ label: 'Primary', value: 'primary' },
{ label: 'Secondary', value: 'secondary' },
]}
onChange={(value) => updateAttribute(panelIndex, value, "buttonColor", panel.id)}
/>
</FlexBlock>
</Flex>
<Flex>
<FlexBlock className="tpp-attribute">
<TextControl
value={panel.buttonUrl}
label="Button URL"
onChange={(value) => updateAttribute(panelIndex, value, "buttonUrl", panel.id)}
/>
</FlexBlock>
</Flex>
<label class="components-base-control__label css-1v57ksj">Features:</label>
{panel.featureList.map((feature, featureIndex) => {
return (
<Flex>
<FlexBlock>
<TextControl
value={feature}
onChange={(feature) => updateFeaturelist(panelIndex, featureIndex, feature)}
/>
</FlexBlock>
<FlexBlock>
<Button
onClick={() => removeFeature(panelIndex, featureIndex)}
className="tpp-delete-feature"
title="Delete Feature">
<Icon
icon={
"trash"
}
/>
</Button>
</FlexBlock>
</Flex>
)
})}
<Button
onClick={() => addNewFeature(panelIndex)}
className="tpp-add-feature">
Add feature
</Button>
</div>
)
})}
<Button
isPrimary
onClick={() => addNewProduct()}>
Add product
</Button>
</div>
)
}
下面是更新面板的函数:
function updateAttribute(panelIndex, value, el, id) {
let panel = props.attributes.panels.find((item) => item.id == id)
panel[el] = value
props.setAttributes({
panels: props.attributes.panels.splice(panelIndex, 1, panel)
})
}
如果你能帮我一点忙,我会很感激的。一切正常
在updateAttribute函数我已经尝试了各种方法来得到这个工作,但没有任何运气。显然,我所期望的是,当在一个面板中输入时,其他面板不会消失。
OK…我已经设法弄明白了——但是花了很长时间!
因此,在调用setAttribute之前,我需要首先更新整个数组(面板)的副本。
function updateAttribute(panelIndex, value, el, id) {
let panel = props.attributes.panels.find((item) => item.id == id)
panel[el] = value
const newPanels = [...props.attributes.panels]
newPanels[panelIndex] = panel;
props.setAttributes({
panels: newPanels
})
}
我仍然有点困惑,为什么我之前的尝试没有工作,但至少我已经设法解决了我的问题。