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
1 Answer
Reset to default 3When 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
评论列表(0条)