javascript - 具有随机值的古腾堡 block 属性未保存

标签 javascript wordpress wordpress-gutenberg

我需要为古腾堡 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/

相关文章:

javascript - 如何在 JSX 中为带有选择器的 const 设置默认变量

php - 多文件上传支持所有浏览器,特别是ie7,ie8和ie9

wordpress - 安装wordpress后弹出Chrome而不是登录页面

reactjs - Gutenberg/React 将动态属性传递给过滤函数

MySQL根据wp_meta值更新wp_posts?

php - 在 WP/woocommerce 中是否有知道用户是否为 'shop_manager' 的功能

wordpress - Wordpress中没有适用于Gutenberg音频 block 的CSS?

javascript - 在页面渲染react-native hooks之前从api获取数据

javascript - 覆盖嵌入在 html 元素中的现有 onkeydown

javascript - 单击后在 wix 上制作 html/java 代码消失