block editor - How can you reset InnerBlock content to base template?

I am looking for a method to re-render the <InnerBlock template... after I've updated some attributes. This is m

I am looking for a method to re-render the <InnerBlock template... after I've updated some attributes.

This is my sample code I am working with. Notice the onChange event is where I need my InnerBlocks to reset back to initial template values.

export const settings = {
    title: __( 'My Block', 'mytextdomain' ),
    description: __( 'Description', 'mytextdomain' ),
    keywords: [ __( 'block' ) ],
    supports: {
        align: false,
        alignWide: false,
    },
    attributes: {
       'someatt' : {
           'type' : 'string'
        }
    },
    edit: function() {

        let TEMPLATE = {
            'myblocks/myblock': {
                'a':'b',
                'c':'d'
            }
        };

        let output = (
            <InspectorControls>
                <PanelBody
                    title={__('Select', 'mytextdomain')}
                    initialOpen={true}>
                    <SelectControl
                         onChange={(selected_id)=>{

                             //TODO: Update InnerBlocks to reset content back to TEMPLATE

                        }}
                        label={ __('Select Item', 'mytextdomain') }
                        options={ options } />
                </PanelBody>
            </InspectorControls>
            <div className="myblock">
                <h1>Some Title</h1>
                <InnerBlocks
                    template={ TEMPLATE }
                    allowedBlocks={ ['myblocks/myblock'] }
                    templateLock={ false }
                    >
                </InnerBlocks>
            </div>
        );

        return output;

    },
    save: () => null
};

How can I reset the InnerBlock content after I've made an attribute change?

Alex

I am looking for a method to re-render the <InnerBlock template... after I've updated some attributes.

This is my sample code I am working with. Notice the onChange event is where I need my InnerBlocks to reset back to initial template values.

export const settings = {
    title: __( 'My Block', 'mytextdomain' ),
    description: __( 'Description', 'mytextdomain' ),
    keywords: [ __( 'block' ) ],
    supports: {
        align: false,
        alignWide: false,
    },
    attributes: {
       'someatt' : {
           'type' : 'string'
        }
    },
    edit: function() {

        let TEMPLATE = {
            'myblocks/myblock': {
                'a':'b',
                'c':'d'
            }
        };

        let output = (
            <InspectorControls>
                <PanelBody
                    title={__('Select', 'mytextdomain')}
                    initialOpen={true}>
                    <SelectControl
                         onChange={(selected_id)=>{

                             //TODO: Update InnerBlocks to reset content back to TEMPLATE

                        }}
                        label={ __('Select Item', 'mytextdomain') }
                        options={ options } />
                </PanelBody>
            </InspectorControls>
            <div className="myblock">
                <h1>Some Title</h1>
                <InnerBlocks
                    template={ TEMPLATE }
                    allowedBlocks={ ['myblocks/myblock'] }
                    templateLock={ false }
                    >
                </InnerBlocks>
            </div>
        );

        return output;

    },
    save: () => null
};

How can I reset the InnerBlock content after I've made an attribute change?

Alex

Share Improve this question edited Aug 13, 2019 at 13:54 AlexBik asked Aug 12, 2019 at 16:54 AlexBikAlexBik 111 silver badge3 bronze badges 2
  • Hi Alex, could you share the code from that component? – Alvaro Commented Aug 12, 2019 at 23:36
  • @Alvaro - I've just added by block registration code – AlexBik Commented Aug 13, 2019 at 6:56
Add a comment  | 

1 Answer 1

Reset to default 3

When we register a block type we define how the block structure should be in the moment it is added to the editor. After the block type is added to the editor we have an actual block.

The initial template prop in the InnerBlock defines which innerBlocks should be added when adding the (root) block type. Once added the prop has no effect as the block has already been created. From there on we need to modify that specific block props.

So in your case we need to dispatch an action to modify the block data in the store. We could achieve this with wp.data.dispatch, wp.data.withDispatch or wp.data.useDispatch. My suggestion is to use wp.data.useDispatch which makes use of React hooks.

We modify the block innerBlocks using the replaceInnerBlocks function. This function takes the block clientId and an array of blocks.

The thing here is that we are modifying blocks that might have content. I suggest taking a look at how we can deal with it in this other answer. What we do is take the existent blocks and merge them if necessary with programatically created blocks (using wp.blocks.createBlock).

const { times } = lodash;
const { __ } = wp.i18n;
const { createBlock } = wp.blocks;
const { PanelBody, SelectControl } = wpponents;
const { InnerBlocks, InspectorControls } = wp.blockEditor;
const { useDispatch, useSelect } = wp.data;

const TEMPLATE = [
    [
        "myblocks/myblock",
        {
            a: "b",
            c: "d"
        }
    ]
];

export const settings = {
    title: __("My Block", "mytextdomain"),
    description: __("Description", "mytextdomain"),
    keywords: [__("block")],
    supports: {
        align: false,
        alignWide: false
    },
    attributes: {
        a: {
            type: "string"
        },
        c: {
            type: "string"
        }
    },
    edit: props => {
        const { className, clientId } = props;
        const { replaceInnerBlocks } = useDispatch("core/block-editor");
        const { inner_blocks } = useSelect(select => ({
            inner_blocks: select("core/block-editor").getBlocks(clientId)
        }));

        return (
            <div className="myblock">
                <InspectorControls>
                    <PanelBody title={__("Select", "mytextdomain")} initialOpen={true}>
                        <SelectControl
                            onChange={selected => {
                                let inner_blocks_new = inner_blocks;

                                /*
                                // If we need to add 3 new blocks
                                inner_blocks_new = [
                                    ...inner_blocks,
                                    ...times(3, () =>
                                        createBlock("myblocks/myblock")
                                    )
                                ];
                                */

                                /*
                                // If we need to remove blocks after the third one
                                inner_blocks_new = inner_blocks.slice(0, 3);
                                */

                                replaceInnerBlocks(clientId, inner_blocks_new, false);
                            }}
                            label={__("Select Item", "mytextdomain")}
                            options={options}
                        />
                    </PanelBody>
                </InspectorControls>
                <h1>{__("Some Title")}</h1>
                <InnerBlocks
                    template={TEMPLATE}
                    allowedBlocks={["myblocks/myblock"]}
                    templateLock={false}
                />
            </div>
        );
    },
    save: () => null
};

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745246590a4618438.html

相关推荐

  • block editor - How can you reset InnerBlock content to base template?

    I am looking for a method to re-render the <InnerBlock template... after I've updated some attributes. This is m

    4小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信