有没有办法在父块中知道您正在编辑该父块的内部块?
Is there a way to know in the parent block that you are editing an inner block of that parent?
父块的 props.isSelected
仅当您在父块内时才为真,但在该块的内部块内编辑时则不然。
如果用户正在编辑此父块的内部块(无论多深),我如何从父块检查
我问是因为我想为父块的 innerBlocks 做某种切换功能,直到您 select 父块并尝试使用 props.isSelected
才可见,但是显然,当您开始编辑内部块时,它会立即消失,因为父级不再 selected
这是一个简单的代码,可以证明我在说什么
registerBlockType('test/parent', {
name: 'Parent',
edit: (props) => {
const template = [['test/child'],['test/child']];
if (props.isSelected) {
return <InnerBlocks template={template}/>;
}
return <div>Click me to see my inner block</div>;
},
save: (props) => {
return <InnerBlocks.Content />;
}
};
registerBlockType('test/child', {
name: 'Child',
parent: ['test/parent'],
edit: (props) => {
return <div>I'm the child I can have some more nested blocks but if you click on me I will be gone because my parent won't want me anymore, I wish somebody could edit me :(</div><InnerBlocks />;
},
save: (props) => {
return <div>I'm the child</div><InnerBlocks.content />;
}
}
是的,这是可能的
Solution
父组件:
在父组件中,你可以在组件中有flag State say childEditted ,还有一个 handler() 说 setChildEditted(),将这个处理程序向下传递给具有 prop
的子组件。
class App extends Component {
State={
childEditted:false
}
setChildEditted = () =>{
this.SetState({childEditted : true});
}
render() {
return (
<div>
<Hello name={this.state.name} />
<p>
<childComponent onChangeHandler={this.setChildEditted} />
</p>
</div>
);
}
}
子组件:
如果您有 panel 子组件将使用此处理程序,您可以在面板的 onChange() 上使用此处理程序道具,即使如果没有面板你也可以在div.
上使用它
class childComponent extends Component {
render() {
return (
<div onChange={this.props.onChangeHandler}>
</div>
);
}
}
这样,无论何时发生更改,父组件状态都会更新,并将更改传达给父组件。
经过大量研究,我自己编写了一个函数来确定是否选择了内部块(需要 wp-data)
这是代码
registerBlockType('test/parent', {
name: 'Parent',
edit: (props) => {
const template = [['test/child'],['test/child']];
if (props.isSelected || hasSelectedInnerBlock(props)) {
return <InnerBlocks template={template}/>;
}
return <div>Click me to see my inner block</div>;
},
save: (props) => {
return <InnerBlocks.Content />;
}
};
function hasSelectedInnerBlock(props) {
const select = wp.data.select('core/editor');
const selected = select.getBlockSelectionStart();
const inner = select.getBlock(props.clientId).innerBlocks;
for (let i = 0; i < inner.length; i++) {
if (inner[i].clientId === selected || inner[i].innerBlocks.length && hasSelectedInnerBlock(inner[i])) {
return true;
}
}
return false;
};
父块的 props.isSelected
仅当您在父块内时才为真,但在该块的内部块内编辑时则不然。
如果用户正在编辑此父块的内部块(无论多深),我如何从父块检查
我问是因为我想为父块的 innerBlocks 做某种切换功能,直到您 select 父块并尝试使用 props.isSelected
才可见,但是显然,当您开始编辑内部块时,它会立即消失,因为父级不再 selected
这是一个简单的代码,可以证明我在说什么
registerBlockType('test/parent', {
name: 'Parent',
edit: (props) => {
const template = [['test/child'],['test/child']];
if (props.isSelected) {
return <InnerBlocks template={template}/>;
}
return <div>Click me to see my inner block</div>;
},
save: (props) => {
return <InnerBlocks.Content />;
}
};
registerBlockType('test/child', {
name: 'Child',
parent: ['test/parent'],
edit: (props) => {
return <div>I'm the child I can have some more nested blocks but if you click on me I will be gone because my parent won't want me anymore, I wish somebody could edit me :(</div><InnerBlocks />;
},
save: (props) => {
return <div>I'm the child</div><InnerBlocks.content />;
}
}
是的,这是可能的
Solution
父组件:
在父组件中,你可以在组件中有flag State say childEditted ,还有一个 handler() 说 setChildEditted(),将这个处理程序向下传递给具有 prop
的子组件。
class App extends Component {
State={
childEditted:false
}
setChildEditted = () =>{
this.SetState({childEditted : true});
}
render() {
return (
<div>
<Hello name={this.state.name} />
<p>
<childComponent onChangeHandler={this.setChildEditted} />
</p>
</div>
);
}
}
子组件:
如果您有 panel 子组件将使用此处理程序,您可以在面板的 onChange() 上使用此处理程序道具,即使如果没有面板你也可以在div.
上使用它 class childComponent extends Component {
render() {
return (
<div onChange={this.props.onChangeHandler}>
</div>
);
}
}
这样,无论何时发生更改,父组件状态都会更新,并将更改传达给父组件。
经过大量研究,我自己编写了一个函数来确定是否选择了内部块(需要 wp-data)
这是代码
registerBlockType('test/parent', {
name: 'Parent',
edit: (props) => {
const template = [['test/child'],['test/child']];
if (props.isSelected || hasSelectedInnerBlock(props)) {
return <InnerBlocks template={template}/>;
}
return <div>Click me to see my inner block</div>;
},
save: (props) => {
return <InnerBlocks.Content />;
}
};
function hasSelectedInnerBlock(props) {
const select = wp.data.select('core/editor');
const selected = select.getBlockSelectionStart();
const inner = select.getBlock(props.clientId).innerBlocks;
for (let i = 0; i < inner.length; i++) {
if (inner[i].clientId === selected || inner[i].innerBlocks.length && hasSelectedInnerBlock(inner[i])) {
return true;
}
}
return false;
};