Wordpress Gutenberg 自动完成 - 保存属性

Wordpress Gutenberg autocomplete - saving attributes

我想开发一个自定义块,让用户从自动完成中选择一些信息。我设法在编辑功能上创建自动完成组件。

用户可以 select 一个项目,但我不知道如何处理属性保存。

我正在尝试将 selected 项目保存为属性 package_name。我在自动完成组件上创建了 onChange 函数,但 event.target.value 未定义。

这是我来自 block.js

的代码
const { __ } = wp.i18n; // Import __() from wp.i18n
const {  AlignmentToolbar,
        BlockControls,
        registerBlockType } = wp.blocks; 
const { RichText } = wp.editor;
const { Autocomplete, } =wp.components;


const MyAutocomplete = () => {
    const autocompleters = [
        {
            name: 'fruit',   
            triggerPrefix: '@',   
            options: [
                {  name: 'Apple', id: 1 },
                {  name: 'Orange', id: 2 },
                {  name: 'Grapes', id: 3 },
                {  name: 'test', id: 4 },
            ],

            getOptionLabel: option => (
                <span>
                  { option.name }
                </span>
            ),

            getOptionKeywords: option => [ option.name ],

            isOptionDisabled: option => option.name === 'Grapes',

            getOptionCompletion: option => (
                <abbr title={ option.name }>{ option.name }</abbr>
            ),
        }
    ];

    function onChangeAuto(newContent){
        console.log('autocompletexx '+newContent);
    }

    function onSelectAuto(event){
        console.log(event.target);
           console.log( event.target.value);
    }

    return (
        <div>
            <Autocomplete completers={ autocompleters }>
                { ( { isExpanded, listBoxId, activeId } ) => (
                    <div
                        contentEditable
                        suppressContentEditableWarning
                        aria-autocomplete="list"
                        aria-expanded={ isExpanded }
                        aria-owns={ listBoxId }
                        aria-activedescendant={ activeId }
                        onChange={onChangeAuto }
                        onSelect={onSelectAuto}

                    >
                    </div>
                ) }
            </Autocomplete>
            <p class="autocomplete_p">Type @ for triggering the autocomplete.</p>
        </div>
    );
};




registerBlockType( 'residence-gutenberg-block/membership-package-settings', {
    title: __( 'Residence - Membership Package Settings' ), // Block title.
    icon: 'shield', 
    category: 'common', 
    keywords: [
        __( 'membership-package-settings' ),
    ],
        attributes:{
            package_id:{
                type:'string',
                select:'p'
            },
            package_name:{
                type:'string',
            },
        },


    edit: function( props ) {

                const { attributes: {package_name}, className,setAttributes,isSelected } = props;               
        return (
            <div className={ props.className }>
                            <form>
                                <label className="wpresidence_editor_label">Current Package: {package_name}</label>
                                <MyAutocomplete></MyAutocomplete>
                             </form>

            </div>

        );
    },

    save: function( props ) {
              // Rendering in PHP
                return null;

    },
} );

onChangeonSelect传递给div元素是行不通的,因为这些属性只适用于表单字段元素(如input, select、等)。

我查看了文档和源代码,没有找到任何处理案例的细节或官方方法。

但是,我看到了两种获取所选值的可能方法:

1。使用自动完成 onReplace prop

查看 Autocomplete's source code,我注意到 onSelect 回调调用 onReplace 属性并将所选选项作为数组。它可能不适合所有情况,但您可以尝试一下!对于您的情况可能就足够了!您可以尝试将您的处理程序添加到 onReplace,如下所示:

<Autocomplete
  onReplace={ option => { console.log(option) } }
  completers={ autocompleters }>
  { ( { isExpanded, listBoxId, activeId } ) => (
    <div
      contentEditable
      suppressContentEditableWarning
      aria-autocomplete="list"
      aria-expanded={ isExpanded }
      aria-owns={ listBoxId }
      aria-activedescendant={ activeId }
    />
  ) }
</Autocomplete>

2。手动监听 <div /> 变化

您可以将 onInputonBlur 侦听器添加到 <div />,具有不受控制的反应 div 组件并且当 div 的值为changed 那么我们可以将更改后的值保留在父组件的状态中。

这里有一个很好的讨论,描述了这些技术:React.js: onChange event for contentEditable

好的想法是已经有一个插件(基于这个讨论)可以为你做这件事:react-contenteditable

首先,您必须将 <MyAutocomplete /> 组件转换为有状态(非功能性)组件,然后:

import ContentEditable from 'react-contenteditable'

// Boilerplate ...

<Autocomplete completers={ autocompleters }>
  { ( { isExpanded, listBoxId, activeId } ) => (
    <ContentEditable
      html={this.state.html}
      onChange={this.handleChange}
      contentEditable
      suppressContentEditableWarning
      aria-autocomplete="list"
      aria-expanded={ isExpanded }
      aria-owns={ listBoxId }
      aria-activedescendant={ activeId }
    />
  ) }
</Autocomplete>

结论

我很惊讶 Autocomplete's documentation 中没有关于此案例的任何详细信息。我想这是因为以下声明 (27.08.2018):

Gutenberg is being developed on GitHub, and you can try an early beta version today from the plugin repository. Though keep in mind it’s not fully functional, feature complete, or production ready.

但是,上述两种方法中的一种都会对您有所帮助,直到它们提供完整的 API 来使用它们的组件。

我建议您继续用自己的组件包装 Wordpress 的 <Autocomplete /> - 以便稍后在他们发布完整的 API.

时轻松重构您的代码

如有任何疑问,请随时在下方发表评论。