我需要为古腾堡 block 提供一个唯一的 ID,但由于我没有找到轻松实现的方法,所以我选择使用随机值来获取可能唯一的数字(我必须非常不幸的是它在同一页面中两次生成相同的数字)。
但是有一个问题...每次我保存 block 时,它都会自行损坏,因为每次都会重新创建 ID,即使这只是默认值,因此只有在刚刚创建 block 时才应使用它。
这是我的 block :
registerBlockType('materialize-fcd/gallery-block', {
title: "Material Gallery - Galleria",
icon: 'images-alt',
category: 'common',
attributes: {
images: {
type: 'array',
default: null
},
ids: {
type: 'array',
default: null
},
size: {
type: 'string',
default: 'full'
},
s: {
type: 'number',
default: 6
},
m: {
type: 'number',
default: 4
},
l: {
type: 'number',
default: 3
},
lightbox:{
type: 'string',
default: 'gal_'+Math.floor(Math.random() * 9000)
}
},
edit(props) {
const {
setAttributes,
attributes,
} = props;
function changeS(newValue) {
setAttributes({
s: newValue
})
}
function changeM(newValue) {
setAttributes({
m: newValue
})
}
function changeL(newValue) {
setAttributes({
l: newValue
})
}
function onChangeSize(value) {
setAttributes({
size: value
})
}
function onChangeLightbox(value) {
setAttributes({
lightbox: value
})
}
function onImagesSelect(imageObject) {
var id_array = imageObject.map(image => image.id);
setAttributes({
images: imageObject,
ids: id_array
})
console.log(attributes.images);
}
var choices = [];
if (attributes.images != null) {
//ciclo le immagini
for(var i in attributes.images){
//ciclo le sizes
for (var name in attributes.images[i].sizes) {
if (!choices.map(choice=>choice.value).includes(name)){
var choice = {
value: name,
label: name
}
if(name == attributes.size) choice.selected = true;
choices.push(choice);
}
}
}
}
var mediaButton = (<MediaUpload onSelect={onImagesSelect} type="image"
value={attributes.ids}
render={ ({ open}) => { return (
<button onClick={open}>
Choose image
</button>);
}
}
multiple = 'add'
/>);
var images = [];
for (var i in attributes.images) {
images.push(<img style={{"max-width" : "150px", "max-height" : "150px"}} src={attributes.images[i].sizes.full.url}/>);
}
return ([(
<InspectorControls>
<PanelBody title='Column Size'>
<PanelRow>
<RangeControl
label="Mobile (S)"
value={ attributes.s }
onChange={changeS}
min={ 0 }
max={ 12 }
/>
</PanelRow>
<PanelRow>
<RangeControl
label="Tablets (M)"
value={ attributes.m }
onChange={changeM}
min={ 0 }
max={ 12 }
/>
</PanelRow>
<PanelRow>
<RangeControl
label="Desktops (L)"
value={ attributes.l }
onChange={changeL}
min={ 0 }
max={ 12 }
/>
</PanelRow>
</PanelBody>
<PanelBody title='Image Size'>
<PanelRow>
<SelectControl
label='Image size:'
value={attributes.size}
onChange={onChangeSize}
options={choices}
/>
</PanelRow>
</PanelBody>
<PanelBody title='Lightbox'>
<PanelRow>
<TextControl
label='Gallery ID:'
value={attributes.lightbox}
onChange={onChangeLightbox}
/>
</PanelRow>
</PanelBody>
<PanelBody title='Images'>
<PanelRow>
{mediaButton}
</PanelRow>
</PanelBody>
</InspectorControls>
),(
<div>
{attributes.className ?'CLASS: ' + attributes.className : null}
{attributes.className ?<br/> : null}
{mediaButton}
<br/>
{attributes.images != null ? images : ''}
</div>
)]);
},
save(props) {
const { attributes, className } = props;
var images = [];
var cols = (props.attributes.s != 0 ? ' s' + props.attributes.s : '') + (props.attributes.m != 0 ? ' m' + props.attributes.m : '') + (props.attributes.l != 0 ? ' l' + props.attributes.l : '') + (props.attributes.className ? ' '+props.attributes.className : '');
for (var i in attributes.images) {
images.push(
<div class={'col' + cols}>
<a sl={(attributes.lightbox == '' || attributes.lightbox == null) ? null : attributes.lightbox} href={attributes.images[i].sizes.full.url} class={(attributes.className ? attributes.className + ' ' : '')+'waves-effect waves-light img gal z-depth-2'}>
<img src={attributes.images[i].sizes[attributes.size].url} />
</a>
</div>
);
}
return (
<div class="row">
{images}
</div>
);
}
})
这是我得到的错误:
Block validation failed
Content generated by `save` function:
<div class="row" class="wp-block-materialize-fcd-gallery-block"><div class="col s6 m4 l3"><a sl="gal_7827" href="https://www.torvaianicahotel.it/wp-content/uploads/2019/07/IMG-20181206-WA0010.jpg" class="waves-effect waves-light img gal z-depth-2"><img src="https://www.torvaianicahotel.it/wp-content/uploads/2019/07/IMG-20181206-WA0010.jpg"/></a></div></div>
Content retrieved from post body:
<div class="row" class="wp-block-materialize-fcd-gallery-block"><div class="col s6 m4 l3"><a sl="gal_2133" href="https://www.torvaianicahotel.it/wp-content/uploads/2019/07/IMG-20181206-WA0010.jpg" class="waves-effect waves-light img gal z-depth-2"><img src="https://www.torvaianicahotel.it/wp-content/uploads/2019/07/IMG-20181206-WA0010.jpg"/></a></div></div>
两者之间的唯一区别是随机数不同,所以似乎灯箱属性没有被保存,并且每次都会重新实例化为默认值......? 知道为什么会发生这种情况吗?
编辑:
似乎我设法通过将默认值设置为 null 并检查编辑是否为 null,然后将属性设置为随机值(如果为 null)来修复它...
我不知道为什么会这样,所以如果有人可以解释我,我仍然会对正确的解释感兴趣。 (这就是为什么我没有回答自己)
最佳答案
这就是您的 block 遇到错误的原因:
根据渲染的save
输出检查 block 验证。当您加载 block 编辑器并且重新生成的 save
输出标记没有更改时,就不会出现错误。
就您而言,由于您有一个始终随机生成的属性,因此渲染的 save
输出每次也会发生变化。因此,每次运行 save
函数时,您总是会获得一个唯一的标记,并使该 block 无效。
通过将属性的默认值更改为 null
,然后仅在其为 null
时生成唯一 ID,这样可以防止将来加载时重新生成该值并使 block 无效.
此外,每个 block 都有一个名为 clientId 的属性,它已经是一个随机的唯一 ID,因此使用它而不是生成自己的 ID 可能也是一个好主意。
关于javascript - 具有随机值的古腾堡 block 属性未保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57972331/