我有一个定制的Gutenberg块,它试图获取一个字符串数组,并将它们保存为<li>元素。一切正常工作,并正确显示给最终用户,但我得到验证错误后,重新加载编辑器。
下面是验证错误:
Expected:
<div class="wp-block-ggcn-blocks-query-string-content"><span class="data-drop" newtab=""></span><ul class="tabs"><li class="tab"><li class="tab">Tab1</li></li><li class="tab"><li class="tab">Tab2</li></li></ul><p class="custom-content"></p></div>
Actual:
<div class="wp-block-ggcn-blocks-query-string-content"><span class="data-drop" newtab=""></span><ul class="tabs"><li class="tab">Tab1</li><li class="tab">Tab2</li></ul><p class="custom-content"></p></div>以下是我的保存功能:
save({attributes, className}) {
const { tabs, newTab, content } = attributes;
return (
<div className={className}>
<span className="data-drop" newtab={newTab}></span>
<ul className="tabs">
{tabs.map(tab => {
return <li className="tab">{tab}</li>;
})}
</ul>
</div>
);
}下面是我解析属性的方式:
attributes: {
tabs: {
type: 'array',
source: 'children',
selector: 'ul.tabs',
default: []
}
}显然,当我只想要文本时,我正在解析整个HTML列表元素。但是,当我将选择器更改为ul.tabs > li时,我只获得单个元素的文本,超过一个项的列表无法验证。
有人能帮助我理解如何获得一个文本值数组吗?
发布于 2019-04-01 11:32:07
我找到了一个解决办法,这是由@tmdesigned的答案引发的,我将把它作为一个答案发布。这是不漂亮的,我不认为它可以是“规范”的答案,但希望它能帮助我们实现。
因此,首先,我使用一个source: children保存属性:
tabs: {
type: 'array',
source: 'children',
selector: 'ul.tabs',
default: []
}这意味着,在初始保存时,我处理的是一个字符串数组,但在编辑器中的后续加载中,我处理的是一个对象数组,因为我的源类型的子元素本身是在列表中提取<li>元素,而不是元素的文本值。
我的解决方案是对这些元素进行映射,并将它们转换回字符串数组。这必须在edit函数和save函数中完成。
const tabValues = tabs.map(tab => {
if (typeof(tab) === 'object')
return tab.props.children[0];
return tab;
});然后在后面的输出中,我可以这样输出:
{tabValues.map(tab => <li key={tab} className="tab">{tab}</li>)}如果有人有一个完全依赖于数据解析的解决方案,并且不需要这个解决方案,我将将其标记为答案。
发布于 2019-03-31 09:37:26
当您将属性的源设置为子元素时,它会为您提供DOM元素,即包含包装HTML,而不仅仅是内部文本。
所以你所看到的行为,你可能已经知道了,就是HTML元素被嵌套在自己的内部。您正在将内容包装在<li>中,后者被包装在<li>中,可能再次被包装在<li>中,依此类推。
这部分我很确定。下面的解决方案是我对如何做到这一点的理解,但是由于还没有完成这种类型的属性选择器,所以我还没有对它进行充分的测试。话虽如此,我认为你们正在寻找的更接近于:
attributes: {
tabs: {
type: 'array',
source: 'query',
selector: 'ul.tabs',
default: [],
query: {
val: {
type: 'string',
selector: 'li',
source: 'text',
},
}
}所以我们用一个属性创建了一个对象数组,这个属性来自每个子文本。然后,在保存函数中,必须具体地从val选择器的内部文本中提取我们刚刚指定的新的li属性:
save({attributes, className}) {
const { tabs, newTab, content } = attributes;
return (
<div className={className}>
<span className="data-drop" newtab={newTab}></span>
<ul className="tabs">
{tabs.map(tab => {
return <li className="tab">{tab.val}</li>;
})}
</ul>
</div>
);
}https://wordpress.stackexchange.com/questions/333016
复制相似问题