Pregunta

Tengo un conjunto de imágenes que tienen ventanas emergentes usando el componente de interfaz de usuario emergente de arranque en el atributo/parámetro de contenido. Me gustaría agregar el componente ReactJS MusicList pero no pude entender la sintaxis o si es posible o no.

var MusicList = React.createClass({
    render : function(){
        return(<ul><li>Here</li></ul>);
    }
});

var PopoverImage = React.createClass({
    componentDidMount:function(){

        $("#"+this.getDOMNode().id).attr('data-component','<span>here</span>');
        $("#"+this.getDOMNode().id).popover({
            html:true,
            content: 
            });
    },

    render:function(){
        return(
            <img href="#" id={this.props.friend.uid+'_popover'} data-html={true} className="smallImage" src={this.props.friend.pic_small} rel="popover" data-original-title={this.props.friend.name} />

                );
    }
});
¿Fue útil?

Solución

Bootstrap no facilita la representación de un componente dinámico dentro de una ventana emergente.Si el popover que desea presentar es estático, simplemente puede usar React's renderComponentToString que toma un componente y devuelve una cadena de HTML a través de una devolución de llamada:

var html = React.renderComponentToString(<MusicList />);
$(this.getDOMNode()).popover({
    html: true,
    content: html
});

Sin embargo, si su componente tiene interactividad, esa estrategia no funcionará porque React nunca tiene la oportunidad de adjuntar controladores de eventos (o ejecutar cualquiera de sus métodos de ciclo de vida personalizados).De hecho, Bootstrap no proporciona los ganchos adecuados para hacer que su contenido emergente sea dinámico.


Dicho esto, es posible hacer que esto funcione parcheando Bootstrap.Creé una demostración en vivo que tiene contenido emergente dinámico:

popover demo screenshot
http://jsfiddle.net/spicyj/q6hj7/

Tenga en cuenta que la hora actual se representa dentro de la ventana emergente mediante un componente de React que se actualiza cada segundo.


¿Cómo se creó este popover?

yo parcheé Bootstrap popover setContent método para tomar un componente de React además de una cadena de texto o HTML.En lugar de usar jQuery html o text métodos que uso React.renderComponent:

// Patch Bootstrap popover to take a React component instead of a
// plain HTML string
$.extend($.fn.popover.Constructor.DEFAULTS, {react: false});
var oldSetContent = $.fn.popover.Constructor.prototype.setContent;
$.fn.popover.Constructor.prototype.setContent = function() {
    if (!this.options.react) {
        return oldSetContent.call(this);
    }

    var $tip = this.tip();
    var title = this.getTitle();
    var content = this.getContent();

    $tip.removeClass('fade top bottom left right in');

    // If we've already rendered, there's no need to render again
    if (!$tip.find('.popover-content').html()) {
        // Render title, if any
        var $title = $tip.find('.popover-title');
        if (title) {
            React.renderComponent(title, $title[0]);
        } else {
            $title.hide();
        }

        React.renderComponent(content,  $tip.find('.popover-content')[0]);
    }
};

Ahora es posible que escribas

$(this.getDOMNode()).popover({
    react: true,
    content: <MusicList />
});

en tus componentDidMount método y hacer que se procese correctamente.Si miras en el JSFiddle vinculado, verás un archivo de propósito general <BsPopover /> contenedor que hice que se encarga de todas las llamadas de Bootstrap por usted, incluida la limpieza adecuada de los componentes emergentes una vez que el componente contenedor se elimina del DOM.

Otros consejos

Hay una nueva biblioteca llamada React-Bootstrap que está experimentando un desarrollo rápido.

https://react-bootstrap.github.io/components.html#popovers

Si incluye este módulo, tiene la capacidad de hacer la ventan de su propio componente que puede guardar en una variable y luego usarlo en su función de render.

su ejemplo:

const positionerInstance = ( <ButtonToolbar> <OverlayTrigger trigger="click" placement="bottom" overlay={<Popover title="Popover bottom"><strong>Holy guacamole!</strong> Check this info.</Popover>}> <Button bsStyle="default">Click</Button> </OverlayTrigger> <OverlayTrigger trigger="hover" placement="bottom" overlay={<Popover title="Popover bottom"><strong>Holy guacamole!</strong> Check this info.</Popover>}> <Button bsStyle="default">Hover</Button> </OverlayTrigger> <OverlayTrigger trigger="focus" placement="bottom" overlay={<Popover title="Popover bottom"><strong>Holy guacamole!</strong> Check this info.</Popover>}> <Button bsStyle="default">Focus</Button> </OverlayTrigger> <OverlayTrigger trigger="click" rootClose placement="bottom" overlay={<Popover title="Popover bottom"><strong>Holy guacamole!</strong> Check this info.</Popover>}> <Button bsStyle="default">Click + rootClose</Button> </OverlayTrigger> </ButtonToolbar> );

React.Render (PosicionInstance, MountNode);

Mi código:

ShowMoreDails: Función (obj, columnas) {

    var popOver = (
        <Popover>
            <table>
                {
                    columns.map(col =>
                            <tr>
                                <td style={{textAlign:'right', padding:5}}>
                                    {col.label}:&nbsp;
                                </td>
                                <td style={{padding:5}}>
                                    {obj[col.key]}
                                </td>
                            </tr>
                    )
                }
            </table>
        </Popover>
    );

    return(
        <OverlayTrigger trigger='click' rootClose placement='left' overlay={popOver}>
            <div className="popover-more">more...</div>
        </OverlayTrigger>
    );

},

Después de haber publicado esta respuesta y haber probado y trabajado un poco con este trabajo, me doy cuenta de que no es óptimo.

Menús desplegable Bootstrap Close tan pronto como el usuario haya interactuado con él. Este podría no ser el comportamiento deseado (en mi caso, estoy insertando un DatePicker y el usuario no puede cambiar el mes sin tener que volver a abrir el menú para elegir la nueva fecha).


Tuve el mismo problema y me fui de una solución fácil y alternativa.

No quería usar React-Bootstrap (otras partes de mi aplicación no reactificaron y usarlo bootstrap, por lo que no quiero tener dos bibliotecas haciendo lo mismo).

El componente desplegable provisto de la caja por Bootstrap casi proporciona las mismas funcionalidades que la popover, excepto que es mucho más flexible. Este es el desplegable de arranque estándar:

<div class="dropdown">
  <button id="dLabel" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    Dropdown trigger
    <span class="caret"></span>
  </button>
  <ul class="dropdown-menu" aria-labelledby="dLabel">
    ...
  </ul>
</div>

Aquí es el mínimo que necesita para que funcione sin romperlo y puede incluir el elemento reaccionar dentro de él:

<div className="dropdown">
  <button data-toggle="dropdown">
    Dropdown trigger
  </button>
  <div className="dropdown-menu">
    <myGreatReactIntervactiveComponent 
      value={this.props.value}
      onChange={this.handleChange}
      onClick={this.handleClick}
      children={this.greatChildrenForMyGreatREactInteractiveComponent}
    />
  </div>
</div>

Todo lo que necesita para mantener es (i) la clase "desplegable" en el DIV de Wrapper, (ii) el atributo de palanca de datos "desplegable" en el gatillo (puede cambiar su activador a cualquier elemento HTML que desee) y (iii) el "menú desplegable" de la clase en el menú desplegable (también puede cambiarlo a cualquier elemento HTML que desee y no tiene que pegar el elemento "UL" propuesto por Bootstrap).

pierde algunas características en comparación con la popover (no puede definir sus propias transiciones, no puede mostrarlas en la parte superior, izquierda o derecha, pero solo a continuación, es un desplegable) pero obtiene un control total sobre el contenido de su desplegable / popover.

Otra forma de resolver esto para incluir el componente de reacción que desea ser el contenido de Popover en la función de renderización del componente que contiene la popover (es decir, 'la página'), pero colóquela dentro de un div que el estilo "se muestra: ninguno;"Así que eso no se muestra y no se ocupa de ningún espacio, sino que también le dé una identificación, por ejemplo.'PopoVovercontent'.Luego, cuando inicializa el contenido del conjunto de popover: document.getlementbyid ("PopoVoverContent").En Bootstrap 4 al menos, se necesita un elemento como contenido.

No es necesario modificar el código de bootstrap de esta manera, facilitando el mantenimiento / actualizaciones.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top