如何在编辑器中重新加载为服务器端Gutenberg块存储的数据

时间:2020-01-02 作者:Pbearne

我正在尝试创建一些“卡片”,以显示来自另一个CPT的数据,因此我需要将post ID存储为块的一部分。

下面的代码在侧栏中有一个select,允许您选择post ID并通过serverSideRender块呈现HTML

查看创建和保存的HTML,如果注释块中有数据(post ID),则在编辑器中重新加载并返回,如下所示

<!-- wp:mvc/block-mvc-offer-details {"data_offer":"2426"} /-->
前端all也可以正常工作并正确呈现代码

但是,当您重新加载/重新编辑帖子时,代码会清除设置和错误,不会设置select,也不会将任何帖子id传递给服务器端代码

注释在没有数据的情况下重置为这个值(我可以在JS剥离的页面源代码中看到正确的字符串)

<!-- wp:mvc/block-mvc-offer-details /-->
我错过了什么???

/**
 * BLOCK: mvc-landing-pages
 *
 * Registering a basic block with Gutenberg.
 * Simple block, renders and saves the same content without any interactivity.
 */

 //  Import CSS.
 import \'./editor.scss\';
 import \'./style.scss\';

  const {__} = wp.i18n; // Import __() from wp.i18n
  const {registerBlockType} = wp.blocks; // Import registerBlockType() from wp.blocks
  const {InspectorControls} = wp.blockEditor;
  const {Spinner, PanelBody, SelectControl,RangeControl,PanelRow,FormToggle} = wp.components;
  const {withSelect} = wp.data;
  const {Fragment} = wp.element;
  const {serverSideRender: ServerSideRender} = wp;


  /**
   * Register: a Gutenberg Block.
   *
   * Registers a new block provided a unique name and an object defining its
   * behavior. Once registered, the block is made editor as an option to any
  * editor interface where blocks are implemented.
   *
   * @link https://wordpress.org/gutenberg/handbook/block-api/
   * @param  {string}   name     Block name.
   * @param  {Object}   settings Block settings.
   * @return {?WPBlock}          The block, if it has been successfully
   *                             registered; otherwise `undefined`.
   */
  registerBlockType(\'mvc/block-mvc-offer-details\', {
// Block name. Block names must be string that contains a namespace             prefix. Example: my-plugin/my-custom-block.
title: __(\'MVC Offer details - MVC Block\'), // Block title.
icon: \'tickets-alt\', // Block icon from Dashicons → https://developer.wordpress.org/resource/dashicons/.
category: \'mvc-blocks\', // Block category — Group blocks together based on common traits E.g. common, formatting, layout widgets, embed.
keywords: [
    __(\'mvc — CGB Block\'),
    __(\'Attractions\'),
],
attributes: {
    data_offer: {
        type: \'number\',
    },
},

getEditWrapperProps( props ) {
     console.log(props);
    const { data_offer } = props;
    console.log(data_offer);
    return {
        \'data_offer\': data_offer,
    };
},
/**
 * The edit function describes the structure of your block in the context of the editor.
 * This represents what the editor will render when the block is used.
 *
 * The "edit" property must be a valid function.
 *
 * @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
 *
 *
 * @returns {Mixed} JSX Component.
 */
edit: withSelect(select => {
    return {
        offers: select(\'core\').getEntityRecords(\'postType\', \'offer-landing\', {per_page: -1})
        //, fields: [\'id\', \'name\', \'location\']
    };
})((props) => {
    let {
        attributes: {data_offer},
        className, setAttributes, offers
    } = props;

    if ( !  offers) {
        return (
            <p className={className}>
                <Spinner/>
                {__(\'Loading Resorts\', \'mvc\')}
            </p>
        );
    }

    let options = offers.map(obj => {
        var options = {};
        options = {label: obj.title.rendered, value: obj.id};
        return options;
    });
    options.unshift({label: \'Select Offer\', value: null});

    return (<Fragment>
                <InspectorControls>
                    <PanelBody title={__(\'Offer Settings\')} >
                        <PanelRow>
                            <label
                                htmlFor="mvc-offers"
                            >
                                { __( \'Resort\', \'mvc\' ) }
                            </label>
                            <SelectControl

                                id="mvc-offers"
                                label={__(\'Offer name\', \'mvc\')}
                                value={data_offer}
                                onChange={data_offer => setAttributes({data_offer})}
                                options={options}
                            />
                        </PanelRow>
                    </PanelBody>
                </InspectorControls>

                <ServerSideRender block="mvc/block-mvc-offer-details"
                                  attributes={{
                                      data_offer: data_offer,
                                      class_name: className,
                                  }}
                />
            </Fragment>);
}),


/**
 * The save function defines the way in which the different attributes should be combined
 * into the final markup, which is then serialized by Gutenberg into post_content.
 *
 * The "save" property must be specified and must be a valid function.
 *
 * @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
 *
 * @param {Object} props Props.
 * @returns {Mixed} JSX Frontend HTML.
 */
save: (props) => {

    return null

},});

2 个回复
最合适的回答,由SO网友:websevendev 整理而成

首先跳出来的是:

<!-- wp:mvc/block-mvc-offer-details {"data_offer":"2426"} /-->

这个data_offer 值存储为字符串,而其定义的属性类型为number.

这可能是它在重新加载后被剥离的原因。虽然select(\'core\').getEntityRecords 将ID作为整数返回,在将数据传递给<SelectControl> 然后通过onChange(event.target.value) 它在DOM中丢失了它的类型。

尝试:onChange={data_offer => setAttributes({data_offer: parseInt(data_offer)})}

SO网友:getdave

您可能还想看看the REST API endpoint that handles block rendering for ServerSideRender.

如果我从你的后续帖子中正确理解WP Slack (registration required) 要将帖子ID作为块属性传递。在这种情况下,您需要确保为注册的“post ID”具有匹配的属性block-mvc-offer-details 块这是因为REST API端点attributes 论点calls get_attributes() as it expects the attributes to match those registered on the block.

相关推荐