带有ToggleControl的Rerender核心模板,但它不识别块类型

时间:2021-06-07 作者:Mien Sao

嘿,伙计们,我想改变一下const TEMPLATE = [template] 动态使用<InnerBlocks template={TEMPLATE} /> 组成部分基于切换,我想删除我的“核心/图像”块。我试图用state创建它,并在切换模板和列时设置它们的状态。Gutenberg给出了块类型“r”无法识别的错误。

我的索引。块的js文件可以在这里找到

const { __ } = wp.i18n;
import \'./styles/editor.scss\'
import \'./styles/style.scss\'
import edit from \'./edit\';
import save from \'./save\';

/**
 * Register block
 */

export const name = \'toolbox/three-cta\';

export const settings = {
    title: __("Three CTA Block"),
    description: __("Display CTA block"),
    category: "widget",
    icon: "awards",
    attributes: {
        paragraph: {
            type: \'string\',
            default: \'\',
            source: \'html\',
            selector: \'p\'
        },
        heading: {
            type: \'string\',
            source: \'html\',
            selector: \'h2\'
        },
        cards: {
            type: \'number\',
            default: 0,
        },
        toggleImg: {
            type: \'boolean\',
            default: false,
        }
    },
    edit,
    save,
}

并在编辑中。js这些属性会发生更改。我认为这与我可能设置的核心块有关。但我没有更改这些核心区块的名称,所以我不明白古腾堡为什么不认识它。

import { InnerBlocks, InspectorControls } from "@wordpress/block-editor";
import { __ } from "@wordpress/i18n";
import { PanelBody, PanelRow, RangeControl, ToggleControl } from "@wordpress/components";
import { useDispatch, useSelect } from "@wordpress/data";
import { createBlock } from "@wordpress/blocks";
import { useState } from "@wordpress/element";
const { times } = lodash;


// const TEMPLATE = [
// The template that should be reproduced. Based on the toggle  [ "core/image", {} ], should be removed
//  [ \'core/heading\', { placeholder: \'Three CTA Block\' } ],
//  [ \'core/columns\', {}, [
//      [ \'core/column\', {}, [
//          [ "core/image", {} ],
//          [ "core/heading", { placeholder: __( "Toolbox CTA" ) } ],
//          [ "core/paragraph", { placeholder: "CTA Description" } ],
//          [ "core/button", { placeholder: "Call to Action" } ],
//      ]
//      ],
//      [ \'core/column\', {}, [
//          [ "core/image", {} ],
//          [ "core/heading", { placeholder: __( "Toolbox CTA" ) } ],
//          [ "core/paragraph", { placeholder: "CTA Description" } ],
//          [ "core/button", { placeholder: "Call to Action" } ],
//      ]
//      ],
//      [ \'core/column\', {}, [
//          [ "core/image", {} ],
//          [ "core/heading", { placeholder: __( "Toolbox CTA" ) } ],
//          [ "core/paragraph", { placeholder: "CTA Description" } ],
//          [ "core/button", { placeholder: "Call to Action" } ]
//      ]
//      ],
//  ]
//  ] ];

export default function edit( props ) {
    const { className, attributes, setAttributes, clientId } = props;

    // code for the rangeControl Innerblocks doesnt affect the code (if not clicked on the rangeControls)
    const { replaceInnerBlocks } = useDispatch( "core/block-editor" );
    let { inner_blocks } = useSelect( select => ( {
        inner_blocks: select( "core/block-editor" ).getBlocks( clientId )
    } ) );

    let [column, setColumn] = useState([ \'core/column\', {}, [
        [ "core/heading", { placeholder: __( "PLACEHOLDER" ) } ],
        [ "core/paragraph", { placeholder: "CTA P" } ],
        [ "core/button", { placeholder: "CTA Button" } ],
    ]])


    const [template, setTemplate] = useState([
        ["core/heading", { placeholder: "Three CTA Block" }],
        ["core/columns", {}, [...column]],
    ])



    const toggleChange = (value) => {
        setAttributes({ toggleImg: value })
        // const newColumn = column += [\'core/column\', {}, [["core/image", {}],]];
        const newColumn = [ \'core/column\', {}, [
            [ "core/image", {} ],
            [ "core/heading", { placeholder: __( "Toolbox CTA" ) } ],
            [ "core/paragraph", { placeholder: "CTA Description" } ],
            [ "core/button", { placeholder: "Call to Action" } ],
        ]]

        setColumn(newColumn);
        setTemplate([
            ["core/heading", { placeholder: "Three CTA Block" }],
            ["core/columns", {}, [...newColumn]],
        ])

    }

    const getInspector = () => {
        return (
                <InspectorControls>
                    <PanelBody
                            title="Add columns"
                            initalOpen={true}
                    >
                        <PanelRow>
                            <RangeControl
                                    label="columns"
                                    value={attributes.cards}
                                    min={0}
                                    max={3}
                                    onChange={count => {
                                        let new_innerblocks = inner_blocks
                                        if ( attributes.cards < count ) {
                                            new_innerblocks = [
                                                ...inner_blocks,
                                                ...times( count - attributes.cards, () =>
                                                        createBlock( "toolbox/three-cta" )
                                                )
                                            ];
                                        } else if ( attributes.cards > count ) {
                                            inner_blocks = inner_blocks.slice( 0, count )
                                        }
                                        replaceInnerBlocks( clientId, new_innerblocks, false );
                                    }}
                            />
                        </PanelRow>
                        <PanelRow>
                            <ToggleControl
                                    label="Toggle me"
                                    checked={attributes.toggleImg}
                                    onChange={(value) => toggleChange(value)}
                            />
                        </PanelRow>
                    </PanelBody>
                </InspectorControls>
        )
    }

    return (
            <>
                {getInspector()}
                <div className={className}>
                    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/foundation.min.css" integrity="sha256-ogmFxjqiTMnZhxCqVmcqTvjfe1Y/ec4WaRj/aQPvn+I=" crossOrigin="anonymous"/>
                    <div className="grid-x">
                        <div className="cell small-12">
                            <InnerBlocks template={template} templateLock="true"/>
                        </div>
                    </div>
                </div>
            </>
    );
}

1 个回复
SO网友:bosco

整洁的实现:)

导致该错误的原因如下:

    const [template, setTemplate] = useState([
        ["core/heading", { placeholder: "Three CTA Block" }],
        ["core/columns", {}, [...column]],
    ])
以及这里:

        setTemplate([
            ["core/heading", { placeholder: "Three CTA Block" }],
            ["core/columns", {}, [...newColumn]],
        ])
如果存在,块模板块项数组的第三个元素应该是内部块项数组的数组,但在上述两种情况下,您都将单个块项的内容分散到内部块容器中。

块名称"r" 错误消息中是块模板API试图处理字符串中的字符的结果"core/column" 作为块项数组:

Block template API attempting to process a misplaced string

我认为正确的解决方案是在这两种情况下都删除数组扩展操作符。