首页 > 解决方案 > 古腾堡区块的范围问题

问题描述

我有一个 Gutenberg 块,它允许用户以单选按钮和带有可能答案的标签的形式定义一个问题和一组选项。我可以添加块的实例,更新选项的问题和标签。到目前为止,一切都很好。但是,如果我现在添加块的另一个实例,选项的标签不是我期望的空字符串默认值,而是来自块的另一个实例的值。其他属性不会发生这种情况;只有选项数组。我只是无法弄清楚为什么存在这个范围界定问题。这是我的 JSX;

import './editor.scss';
import './style.scss';

const { __, } = wp.i18n;
const { registerBlockType, } = wp.blocks;
const { Button, IconButton, PanelBody, PanelRow, ToggleControl, TextControl, } = wp.components;
const { RichText, } = wp.blockEditor;
const { InspectorControls, } = wp.editor;
const { Fragment, } = wp.element;

const icon = () => {
    return (
        <svg width="20px" height="20px" viewBox="0 0 512 512">
            <path d="M32.39 224C14.73 224 0 238.33 0 256s14.73 32 32.39 32a32 32 0 0 0 0-64zm0-160C14.73 64 0 78.33 0 96s14.73 32 32.39 32a32 32 0 0 0 0-64zm0 320C14.73 384 0 398.33 0 416s14.73 32 32.39 32a32 32 0 0 0 0-64zM504 80H136a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h368a8 8 0 0 0 8-8V88a8 8 0 0 0-8-8zm0 160H136a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h368a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8zm0 160H136a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h368a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8z" />
        </svg>
    );
};

registerBlockType( 'myblocks/radio', {
    title: __( 'Radio Buttons' ),
    icon: icon,
    category: 'myblocks-forms',
    render_callback: 'radio_render_callback',
    attributes: {
        input_label: {
            type: 'string',
            default: '',
        },
        input_name: {
            type: 'string',
            default: '',
        },
        input_required: {
            type: 'boolean',
            default: false,
        },
        input_points: {
            type: 'string',
            default: '',
        },
        input_answer: {
            type: 'number',
        },
        input_info: {
            type: 'string',
        },
        input_options: {
            type: 'array',
            default: [{option: '',},{option: '',}],
        },
    },
    keywords: [
        __( '' ),
    ],
    edit: ( props ) => {
        props.setAttributes({ input_name: props.clientId });
        
        const handleAddInput_option = () => {
            const input_options = [ ...props.attributes.input_options ];
            input_options.push( {
                option: '',
            } );
            props.setAttributes( { input_options } );
        };

        const handleRemoveInput_option = ( index ) => {
            const input_options = [ ...props.attributes.input_options ];
            input_options.splice( index, 1 );
            props.setAttributes( { input_options } );
        };

        const handleInput_optionChange = ( option, index ) => {
            const input_options = [ ...props.attributes.input_options ];
            input_options[ index ].option = option;
            props.setAttributes( { input_options } );
        };
        
        const input_optionDisplay = ( ) => {
    
            if ( props.attributes.input_options.length ) {
    
                return props.attributes.input_options.map( ( input_option, index ) => {
                    return <div key={ index } >
                    <input 
                        type="radio"
                        id={ props.attributes.input_name + ':' + index }
                        name={ props.attributes.input_name }
                        className={ props.attributes.input_answer == index ? 'answer' : '' }
                        onChange={ ( ) => props.setAttributes( { input_answer: index } ) }
                        value={ index }
                        checked={ props.attributes.input_answer == index ? 'checked' : '' }
                    />
                    <label htmlFor={ props.attributes.input_name + ':' + index }></label>
                    <RichText
                        tagName="label"
                        className="option"
                        placeholder='Option goes here...'
                        onChange={ ( option ) => handleInput_optionChange( option, index ) }
                        value={ props.attributes.input_options[index].option }
                    />
                    <IconButton
                        className="remove fal fa-minus"
                        label="Delete Option"
                        onClick={ () => handleRemoveInput_option( index ) }
                    />
                    </div>;
                    ;
                });
            }
        };

        return [
            <InspectorControls key="1">
            
                 <PanelBody title={ __( 'Settings' ) }>
                    {/*
                    <PanelRow>
                        <TextControl id="input_name" label="Name"
                            value={ props.attributes.input_name }
                            onChange={ (newContent) => props.setAttributes( { input_name: newContent } ) }
                            />
                    </PanelRow>
                    */}
                    <PanelRow>
                        <ToggleControl
                            id="input_required"
                            label="Required"
                            checked={props.attributes.input_required}
                            onChange={() => props.setAttributes( { input_required: !props.attributes.input_required } ) }
                        />
                    </PanelRow>
                        
                    <PanelRow>
                        <TextControl id="input_points" label="Points"
                            value={ props.attributes.input_points }
                            onChange={ (newContent) => props.setAttributes( { input_points: newContent } ) }
                        />
                    </PanelRow>

                    <PanelRow>
                        <TextControl id="input_info" label="Additional Info"
                            value={ props.attributes.input_info }
                            onChange={ (newContent) => props.setAttributes( { input_info: newContent } ) }
                        />
                    </PanelRow>
                </PanelBody>
            </InspectorControls>,
            <div key="2" className={ props.className  + ' myblock-input' }>
                <RichText
                    tagName="label"
                    placeholder='Question goes here...'
                    className="question"
                    onChange={ (newContent) => props.setAttributes( { input_label: newContent } ) }
                    value={ props.attributes.input_label }
                />
                {/* <span>{ ' (' + props.attributes.input_points + ' points)' }</span> */} 
                <span value={ props.attributes.input_required } className="required"> *</span>
                { input_optionDisplay() }
                <RichText
                    tagName="p"
                    placeholder='Info goes here...'
                    className="input-info"
                    onChange={ (newContent) => props.setAttributes( { input_info: newContent } ) }
                    value={ props.attributes.input_info }
                />
                <Button
                    className="add fal fa-plus-circle"
                    label="Add Option"
                    isDefault
                    onClick={ handleAddInput_option.bind( this ) }
                ></Button>
            </div>,
        ];
    },
} );

标签: reactjsgutenberg-blocks

解决方案


推荐阅读