Question

J'ai un ensemble d'images qui ont des popovers utilisant le composant d'interface utilisateur popover bootstrap dans l'attribut/paramètre de contenu. Je voudrais ajouter le composant ReactJS MusicList mais je n'arrive pas à comprendre la syntaxe ou si c'est possible ou non.

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} />

                );
    }
});
Était-ce utile?

La solution

Bootstrap ne facilite pas le rendu d'un composant dynamique dans un popover.Si le popover que vous souhaitez présenter est statique, vous pouvez simplement utiliser le popover de React renderComponentToString qui prend un composant et renvoie une chaîne HTML via un rappel :

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

Cependant, si votre composant a une interactivité, cette stratégie ne fonctionnera pas car React n'a jamais la possibilité d'attacher des gestionnaires d'événements (ou d'exécuter l'une de vos méthodes de cycle de vie personnalisées).En effet, Bootstrap ne fournit pas les hooks appropriés pour rendre votre contenu popover dynamique.


Cela dit, il est possible de faire fonctionner cela en patchant Bootstrap.J'ai créé une démo en direct avec un contenu popover dynamique :

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

Notez que l'heure actuelle est rendue dans le popover par un composant React qui se met à jour toutes les secondes.


Comment ce popover a-t-il été créé ?

j'ai patché Popovers Bootstrap setContent méthode pour prendre un composant React en plus d'une chaîne HTML ou texte.Au lieu d'utiliser jQuery html ou text méthodes, j'utilise 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]);
    }
};

Maintenant, il t'est possible d'écrire

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

dans ton componentDidMount méthode et faites-la restituer correctement.Si vous regardez dans le JSFiddle lié, vous verrez un outil à usage général <BsPopover /> wrapper que j'ai créé et qui prend en charge tous les appels Bootstrap pour vous, y compris le nettoyage correct des composants popover une fois que le composant wrapper est supprimé du DOM.

Autres conseils

Il existe une nouvelle bibliothèque appelée React-Bootstrap qui est en cours de développement rapide.

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

Si vous incluez ce module, vous avez la possibilité de faire du popover son propre composant que vous pouvez enregistrer dans une variable puis utiliser dans votre fonction de rendu.

Leur exemple :

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(positionerInstance, mountNode);

mon code :

afficherPlus de détails :fonction (obj, colonnes){

    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>
    );

},

Après avoir posté cette réponse et avoir testé et travaillé un peu avec ce travail, je me rends compte que ce n'est pas optimal.

Les menus déroulants Bootstrap fermer dès que l'utilisateur l'a interagi. Cela pourrait ne pas être le comportement souhaité (dans mon cas, j'insère un salepicker et que l'utilisateur ne peut pas changer de mois sans avoir à rouvrir le menu pour choisir une nouvelle date).


J'ai eu le même problème et j'ai proposé une solution facile et alternative.

Je ne voulais pas utiliser React-Bootstrap (d'autres parties de mon application ne sont pas réactivées et utilisent Bootstrap, donc je ne veux donc pas avoir deux bibliothèques qui font la même chose).

Le composant déroulant fourni sur la boîte par Bootstrap fournit presque les mêmes fonctionnalités que la popover, à l'exception de celle-ci est bien plus flexible. Ceci est la liste déroulante Standard Bootstrap:

<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>

Voici le minimum dont vous avez besoin de le faire fonctionner sans le casser et vous pouvez inclure l'élément de réagisme de réaction:

<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>

Tout ce que vous avez besoin de conserver est (i) la classe "Dropdown" sur le wrapper div, (ii) l'attribut Data-Toggle "Dropdown" sur la gâchette (vous pouvez modifier votre déclenchement sur tout élément HTML que vous voulez) et (iii) la classe "Menu Dropdown-" sur la liste déroulante (vous pouvez également le modifier à tout élément HTML souhaité et que vous ne devez pas coller l'élément "UL" proposé par Bootstrap).

Vous perdez quelques fonctionnalités par rapport à la popover (vous ne pouvez pas définir vos propres transitions, vous ne pouvez pas les afficher en haut, à gauche ou à droite, mais seulement ci-dessous - c'est une liste déroulante) mais vous obtenez un contrôle total sur le contenu. de votre liste déroulante / popover.

Une autre façon de résoudre ce problème pour inclure le composant réactif que vous souhaitez être la teneur en POPOVER dans la fonction de rendu du composant contenant la ponphère (c.-à-d. «La page»), mais placez-la à l'intérieur d'un style »Affichage: Aucun;"Donc, cela n'est pas affiché et ne prend pas d'espace, donnez-lui également un identifiant, par ex.'POPOVERContent'.Ensuite, lorsque vous initialisez le contenu du jeu de Popover: Document.getElementByID ("POPOVERContent").Dans Bootstrap 4 au moins, il faut un élément en tant que contenu.

Vous n'avez pas besoin de modifier le code bootstrap de cette façon, ce qui facilite la maintenance / mises à jour.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top