javascript – Mostrar control condicionalmente en Gutenberg

Pregunta:

Tengo este tipo de publicación personalizada con dos metacampos que necesito mostrar como controles de alternancia ( RestrictControl y SubscribeControl ) en la barra lateral PluginDocumentSettingPanel en el editor de Gutenberg. El caso es que solo quiero mostrar SubscribeControl cuando se establece RestrictControl . Este es el código que tengo actualmente, pero no funciona. Cuando activo y desactivo RestrictControl ambos controles siempre se muestran.

¿Algunas ideas?

let RestrictControl = ({ restrict, onUpdateRestrict }) => (
    <ToggleControl
        label={ __( 'Restrict viewing?' ) }
        checked={ restrict }
        onChange={ restrict => onUpdateRestrict( restrict ) }
    />
);

let SubscribeControl = ({ subscribe, onUpdateSubscribe }) => (
    <ToggleControl
        label={ __( 'Add to newsletter?' ) }
        checked={ subscribe }
        onChange={ subscribe => onUpdateSubscribe( subscribe ) }
    />
);

const OptionsPanel = () => {
    const postType = select( 'core/editor' ).getCurrentPostType();
    if ( 'custom_type' !== postType ) {
        return null;
    }

    return (
        <PluginDocumentSettingPanel
            name='options'
            title={ __( 'Options' ) }
            className='options-panel'
        >
            <RestrictControl />
            { restrict && (
                <SubscribeControl />
            ) }
        </PluginDocumentSettingPanel>
    );
}

registerPlugin( 'options-panel', {
    render: OptionsPanel,
})

Respuesta:

Hay 2 problemas principales en su código:

  1. ¿Cuál es esa restrict en su componente OptionsPanel ? ¿Dónde y cómo lo definiste?

  2. Tanto onUpdateRestrict como onUpdateSubscribe no son funciones, por lo que hacer clic en los controles de alternancia dará como resultado un error de JavaScript.

Y si puede mostrar su código completo, probablemente pueda ayudarlo a corregirlo . Sin embargo, sugiero que pruebe el compose paquete para construir el OptionsPanel componente, ya hacerlo de esa manera se puede reducir en gran medida las cosas ayuda fuente y hacer muy fácil para nosotros.

Entonces, con el paquete de compose , los pasos son:

Nota: Estoy usando estas dos meta claves: restrict_viewing y subscribe_to_news , así que asegúrese de cambiarlas por las correctas. (Es decir, use las meta claves adecuadas).

  1. Cargue todas las dependencias de WordPress:

     import { PluginDocumentSettingPanel } from '@wordpress/edit-post'; import { ToggleControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { registerPlugin } from '@wordpress/plugins'; import { withSelect, withDispatch } from '@wordpress/data'; import { compose } from '@wordpress/compose';
  2. Cree el componente principal que básicamente simplemente representa el panel del complemento / barra lateral más los dos controles de alternancia ( RestrictControl y SubscribeControl en la pregunta).

     function OptionsPanelComponent( { // These props are passed by applyWithSelect(). (see step #3) currentPostType, // current post type restrictViewing, // current state of the meta restrict_viewing subscribeToNews, // current state of the meta subscribe_to_news // And these are passed by applyWithDispatch(). (see step #4) onUpdateRestrict, // function which updates the meta restrict_viewing onUpdateSubscribe, // function which updates the meta subscribe_to_news } ) { if ( 'custom_type' !== currentPostType ) { return null; } return ( <PluginDocumentSettingPanel name="options" title={ __( 'Options' ) } className="options-panel" > <ToggleControl label={ __( 'Restrict viewing?' ) } checked={ restrictViewing } onChange={ onUpdateRestrict } /> { restrictViewing && ( <ToggleControl label={ __( 'Add to newsletter?' ) } checked={ subscribeToNews } onChange={ onUpdateSubscribe } /> ) } </PluginDocumentSettingPanel> ); }
  3. Use wp.data.withSelect para 'seleccionar' / recuperar datos de la publicación actual (que se está editando) y pasar los datos al componente anterior ( OptionsPanelComponent ).

    Nota: La select siempre se pasa a la función y esa select es equivalente a wp.data.select .

     const applyWithSelect = withSelect( ( select ) => { const { getEditedPostAttribute, getCurrentPostType } = select( 'core/editor' ); const meta = getEditedPostAttribute( 'meta' ); return { currentPostType: getCurrentPostType(), restrictViewing: meta.restrict_viewing, subscribeToNews: meta.subscribe_to_news, }; } );
  4. Utilice wp.data.withDispatch para definir las funciones para actualizar los datos de la publicación y pasar las funciones al componente en el paso 2 anterior ( OptionsPanelComponent ).

    Nota: El dispatch siempre se pasa a la función y ese dispatch es equivalente a wp.data.dispatch .

     const applyWithDispatch = withDispatch( ( dispatch ) => { const { editPost } = dispatch( 'core/editor' ); return { onUpdateRestrict( restrict ) { const meta = { restrict_viewing: restrict }; editPost( { meta } ); }, onUpdateSubscribe( subscribe ) { const meta = { subscribe_to_news: subscribe }; editPost( { meta } ); }, }; } );
  5. Luego, finalmente, use wp.compose.compose() para 'componer' / envolver los tres componentes anteriores (pueden definirse usando function o const , pero en realidad son componentes). Y este componente 'compuesto' será el que pasemos como devolución de llamada de render para wp.plugins.registerPlugin .

     const OptionsPanel = compose( applyWithSelect, applyWithDispatch )( OptionsPanelComponent ); registerPlugin( 'options-panel', { render: OptionsPanel, } );

Código completo que utilicé para realizar pruebas

Puede encontrarlo aquí , o puede descargar el complemento completo que creé en base a este ejemplo .

Y he intentado y probado que en WordPress 5.4.1 con el valor por defecto post tipo post con las dos claves del meta mencionó anteriormente en esta respuesta.

Solución alternativa

Si no desea utilizar compose() , puede probar este . Pero lo agrego solo porque pensé que me sería útil en el futuro. 🙂

Leave a Comment

Your email address will not be published. Required fields are marked *

web tasarım