Гутенберг: Динамический блок – Показать сохраненные данные в редакторе

Вопрос или проблема

Я пытаюсь создать динамический блок Gutenberg с выпадающим списком. Я завершил создание блока и рендеринг блока с выбранным значением выпадающего списка на фронтенде.

Как установить выпадающий список с предыдущим значением при редактировании поста?

Я пытался получить значение атрибута, используя props.attributes, но получаю undefined.

block.js

const { __ } = wp.i18n;
const { registerBlockType, RichText } = wp.blocks;

registerBlockType( 'gut/new-block', {
    title: __( 'new-block - Test' ),
    category: 'common',
    attributes: {
        category_id: {
            type: 'number'
        }
    },
    edit: function( props ) {
        const { attributes: { category_id }, setAttributes } = props;

        function setCategory( event ) {
            const selected = event.target.querySelector( 'option:checked' );
            setAttributes( { category_id: selected.value } );
            event.preventDefault();
        }

        return (
            <div className={ props.className }>                            
                <select value={ category_id } onChange={ setCategory }>
                    <option value="120">Животные</option>
                    <option value="350">Архитектура</option>
                    <option value="700">Природа</option>
                    <option value="800">Люди</option>
                    <option value="432">Технологии</option>
                </select>                
            </div>
        );
    },
    save ( props ) {
        return null
    },
});

PHP

function gut_my_new_block() {
    wp_register_script(
        'gut-my-new-block',
        plugins_url( 'new-block/dist/blocks.build.js', __FILE__ ),
        array( 'wp-blocks', 'wp-element' )
    );

    register_block_type( 'gut/new-block', array(
        'render_callback' => 'gut_render_block_my_newblock',
        'editor_script' => 'gut-my-new-block',
    ) );
}

add_action( 'init', 'gut_my_new_block' );

function gut_render_block_my_newblock($params) {  
    return '<h3>выбранная категория '.$params['category_id'].'</h3>';
}

Когда атрибут регистрируется с type: 'number', он не вернет строковое значение в объекте атрибутов. Это сбивало меня с толку несколько раз.

Решение заключается в том, чтобы убедиться, что вы устанавливаете значение как число при установке атрибута. Один из способов сделать это:

setAttributes( { category_id: parseInt( selected.value ) } );

Учитывая, что этот вопрос довольно старый, в настоящее время рекомендуется использовать встроенный компонент SelectControl, а не нативный HTML select.

Вам просто нужно получить значение из атрибутов и установить его в <select>. В вашем случае это будет так: <select value={ props.attributes.category_id } onChange={ setCategory }>

В общем, вы мыслите в правильном направлении, но переменная, которую вы объявляете на 13 строке, недоступна за пределами {}, и вы устанавливаете значение как undefined.

Ответ или решение

Для создания динамического блока в Gutenberg с выпадающим списком и корректным отображением ранее сохраненных данных при редактировании, важно правильно работать с атрибутами блока. В вашем коде возникают проблемы из-за неверной инициализации и обработки значений атрибутов. Ниже представлено подробное руководство по решению этой проблемы.

Шаг 1: Инициализация атрибутов

Атрибуты вашего блока следует правильно определять, чтобы они могли корректно сохранять и извлекать данные. Для числовых значений, как в вашем случае со значением category_id, нужно убедиться, что вы обрабатываете их как числа, чтобы избежать ошибок.

Вот как можно это исправить:

attributes: {
    category_id: {
        type: 'number',
        default: 120, // Устанавливаем значение по умолчанию
    }
}

Шаг 2: Использование выпадающего списка

При создании выпадающего списка вы можете использовать компонент SelectControl из библиотеки WordPress, который предоставляет больше возможностей по сравнению с обычным HTML-элементом select. Обратите внимание, как используется category_id из атрибутов:

const { SelectControl } = wp.components;

// ... остальная часть кода

edit: function( props ) {
    const { attributes: { category_id }, setAttributes } = props;

    return (
        <div className={ props.className }>
            <SelectControl
                label={ __( 'Выберите категорию', 'text-domain' ) }
                value={ category_id } // Используем значение из атрибутов
                options={[
                    { label: 'Животные', value: 120 },
                    { label: 'Архитектура', value: 350 },
                    { label: 'Природа', value: 700 },
                    { label: 'Люди', value: 800 },
                    { label: 'Технологии', value: 432 },
                ]}
                onChange={ ( value ) => setAttributes( { category_id: parseInt( value, 10 ) } ) } // Преобразуем в число
            />
        </div>
    );
},

Шаг 3: PHP обработка

Обработчик сервера должен корректно возвращать значение атрибута, чтобы оно отображалось на фронтенде. Параметры передаются в gut_render_block_my_newblock, как у вас это сделано. Проверьте, правильно ли прописано извлечение значения:

function gut_render_block_my_newblock($params) {
    return '<h3>Выбранная категория: '.$params['category_id'].'</h3>';
}

Заключение

Таким образом, исправления, которые вы должны внести в ваш код, заключаются в следующем:

  1. Убедитесь, что атрибут category_id обрабатывается как число (используйте parseInt).
  2. Для более удобного управления и улучшенного пользовательского интерфейса лучше использовать компонент SelectControl.
  3. Проверьте, что обработка данных на серверной стороне корректна и возвращает значения в ожидаемом формате.

Применение данных рекомендаций поможет вам создать Gutenberg блок, который корректно сохраняет и отображает выбранные значения, улучшая взаимодействие пользователя с вашим редактором.

Оцените материал
Добавить комментарий

Капча загружается...