8

我为 Gutenberg 创建了一个自定义横幅图像块,效果很好,但我想知道是否可以将页面标题用作当前横幅文本占位符,直到它被编辑?

在此处输入图像描述

我的编辑功能是

 return [
            el('div', {className:'header-banner'},
                el(
                    element.Fragment,
                    null,
                    controls,
                    el( "div",{
                        className: 'banner-image',
                        style: { backgroundImage: 'url('+attributes.mediaURL+')' }
                    },
                    attributes.title || isSelected ?  el(RichText, {
                            key: 'editable',
                            tagName: "h1",
                            className: "banner-title",
                            //Can i add the page title in here if it is avaiable??
                            //placeholder: i18n.__('Write title…'),
                            value: attributes.title,
                            onChange: function onChange(value) {
                                return props.setAttributes({ title: value });
                            },
                            inlineToolbar: true
                        }) : null 

                    )
                )
            )//header-banner
        ];    

谢谢 :)

4

2 回答 2

12

Gutenberg 使用wp.data存储当前编辑器状态,这是对 Redux 的抽象。要获取标题(或100 多个其他值),我们需要查询core/editor数据存储。Gutenberg 使使用getEditedPostAttribute检索帖子属性变得简单。

一旦我们知道在哪里看,获得标题就很简单了:

const { select } = wp.data;
const title = select("core/editor").getEditedPostAttribute( 'title' );

这有效,但它没有响应。当帖子标题更改时,title不会反映新值。这有点让人失望。

为了反映编辑器标题的变化,我们需要监听core/editor数据存储的变化。有几种方法可以做到这一点。

一种解决方案是定义一个简单的更改处理函数并将其订阅到数据存储更新:

const { select } = wp.data;

function logTitle() {
  const title = select("core/editor").getEditedPostAttribute( 'title' );
  console.log("Editor Title:", title);
}
subscribe(logTitle);

当更新任何 wp.data存储值时,这将触发——这种情况经常发生。

似乎是古腾堡认可的包含数据存储值的方法是使用高阶组件直接包含该值:

const GetTitle = props => <div>{props.title}</div>;

const selectTitle = withSelect(select => ({
  title: select("core/editor").getEditedPostAttribute( 'title' )
}));
const PostTitle = selectTitle(GetTitle);

然后在块的输出中,包含一个<PostTitle />jsx 标签。这比嵌套回调或其他更改处理程序要干净得多。

高阶组件可能难以遵循。简短的解释是它们包装现有组件,生成一些数据,然后返回组件的副本,并将新数据作为 props 传递。这将逻辑与表示分离并有助于可维护性。

GetTitle很简单,它只是一个小组件,它接收一个props带有标题键的对象并吐出一些 html。

withSelect是一个函数构造函数或装饰器。它接受一个函数参数,并返回一个需要一个组件的新函数。通常会立即调用返回的函数(类似于 IIFE),但为了清楚起见,我将其存储在selectTitle变量中。新函数生成一个包含标题的对象,该对象将作为道具传递给传递给的任何组件withSelect。每当更新数据存储时,都会通过一些魔法调用它。

最后,PostTitle包含函数 resultselectTitle是一个预先填充了生成的 props 的组件。然后可以使用标签将此组件放入我们的标记中<PostTitle />。每当更新编辑器数据存储时,更高级别的组件将反映新数据。

于 2018-08-10T18:20:12.663 回答
1

@joemaller 感谢您的帮助。

这是一个示例,演示如何使用传递给的块配置对象withSelect()的属性来包装组件。editregisterBlockType()

组件通过titlevia 道具传递。

如果用户编辑帖子/页面标题,组件将使用新标题重新渲染,因为它的 props 将发生变化。这使其能够“实时”更新。

import { withSelect } from '@wordpress/data'

...

edit: withSelect(
  ( select ) => {
    return {
      title: select( 'core/editor' ).getEditedPostAttribute( 'title' ),
    }
  } )( props => {
    return (
      <div>{ props.title }</div>
    )
} ),
于 2019-09-18T22:21:22.020 回答