1

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

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

我正在尝试将所选项目保存为属性 package_name。我在 Autocomplete 组件上创建了 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;

    },
} );
4

1 回答 1

1

onChange将,传递onSelectdiv元素将不起作用,因为这些属性仅适用于表单字段元素(asinput, select等)。

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

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

1.使用自动完成onReplace道具

查看Autocomplete 的源代码,我注意到onSelect回调调用onReplaceprop 并将所选选项作为数组。它可能不适合所有情况,但你可以试一试!对于您的情况,这可能就足够了!您可以尝试将您的处理程序添加到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>

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

您可以将onInput,onBlur监听器添加到<div />, 具有不受控制的反应 div 组件,当 div 的值发生更改时,我们可以将更改后的值保持在父组件的状态中。

这是一个很好的讨论,描述了这些技术: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 的文档中没有关于这个案例的任何细节。我想这是因为以下声明(27.08.2018):

Gutenberg 正在 GitHub 上开发,您今天可以从插件存储库中试用早期的 beta 版本。但请记住,它的功能不全、功能不完整或生产就绪。

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

我建议您继续<Autocomplete />用您自己的组件包装 Wordpress - 以便稍后在他们发布完整的 API 时轻松重构您的代码。

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

于 2018-08-27T13:26:06.410 回答