Frage

Ich habe eine Reihe von Bildern mit Popovern, die die Bootstrap-Popover-UI-Komponente im Inhaltsattribut / -parameter verwenden Ich möchte die ReactJS-Musiklistenkomponente hinzufügen, konnte aber die Syntax nicht herausfinden oder ob dies möglich ist oder nicht.

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

                );
    }
});
War es hilfreich?

Lösung

Bootstrap macht es nicht einfach, eine dynamische Komponente in einem Popover zu rendern.Wenn das Popover, das Sie präsentieren möchten, statisch ist, können Sie einfach Reacts verwenden renderComponentToString das nimmt eine Komponente und gibt eine HTML-Zeichenfolge über einen Rückruf zurück:

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

Wenn Ihre Komponente jedoch interaktiv ist, funktioniert diese Strategie nicht, da React niemals die Möglichkeit hat, Ereignishandler anzuhängen (oder eine Ihrer benutzerdefinierten Lebenszyklusmethoden auszuführen).In der Tat bietet Bootstrap nicht die richtigen Hooks, um Ihren Popover-Inhalt dynamisch zu gestalten.


Das heißt, es ist möglich, dies durch Patchen von Bootstrap zum Laufen zu bringen.Ich habe eine Live-Demo mit dynamischem Popover-Inhalt erstellt:

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

Beachten Sie, dass die aktuelle Uhrzeit im Popover von einer Reaktionskomponente gerendert wird, die jede Sekunde aktualisiert wird.


Wie wurde dieses Popover erstellt?

Ich habe geflickt Bootstrap-Popovers setContent Methode um eine Reaktionskomponente zusätzlich zu einer HTML- oder Textzeichenfolge zu verwenden.Anstatt jQuery zu verwenden html oder text methoden, die ich benutze 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]);
    }
};

Jetzt ist es Ihnen möglich zu schreiben

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

in Ihrem componentDidMount methode und lassen Sie sie richtig rendern.Wenn Sie in die verknüpfte JSFiddle schauen, sehen Sie einen allgemeinen Zweck <BsPopover /> wrapper, den ich erstellt habe und der sich um alle Bootstrap-Aufrufe für Sie kümmert, einschließlich der ordnungsgemäßen Bereinigung der Popover-Komponenten, sobald die Wrapper-Komponente aus dem DOM entfernt wurde.

Andere Tipps

Nachdem er diese Antwort veröffentlicht hatte und getestet und mit dieser Work ein wenig getestet hat, erkennen ich, dass es nicht optimal ist.

Bootstrap Dropdown-Menüs schließen, sobald der Benutzer damit interagiert hat. Dies ist möglicherweise nicht das gewünschte Verhalten (in meinem Fall, bin ich ein Datumspicker einfüge, und der Benutzer kann den Monat nicht ändern, ohne dass das Menü wiedereröffnet werden muss, um das neue Datum zu wählen).


Ich hatte das gleiche Problem und ich kam mit einer einfachen und alternativen Lösung.

Ich wollte nicht mit React-Bootstrap verwenden (andere Teile meiner App werden nicht reagiert und verwenden Bootstrap, sodass ich nicht zwei Bibliotheken dasselbe haben möchte).

Die in der Box bereitgestellte Dropdown-Komponente liefert fast dieselbe Funktionalitäten wie der Popover, es sei denn, es ist viel flexibler. Dies ist der Standard-Bootstrap-Dropdown:

generasacodicetagpre.

Hier ist das Minimum, das Sie benötigen, um es zu arbeiten, ohne es zu brechen, und Sie können das, welches Reaktionselement darin ist:

generasacodicetagpre.

Alles, was Sie tun müssen, ist (i) die Klasse "Dropdown" auf dem Wrapper DIV, (ii) das Data-Toggle-Attribut "Dropdown" auf dem Trigger (Sie können Ihren Auslöser an das gewünschte HTML-Element ändern) und (iii) das Klassen-Dropdown-Menü "Im Dropdown-Menü" (Sie können es auch an das von Ihnen gewünschte HTML-Element ändern, und Sie müssen das von Bootstrap vorgeschlagene "UL" nicht anhalten.

Sie verlieren ein paar Funktionen im Vergleich zum Popover (Sie können Ihre eigenen Übergänge nicht definieren, Sie können sie nicht oben, links oder rechts anzeigen, sondern nur unten - es ist eine Dropdown-Adresse), aber Sie erhalten die Gesamtkontrolle über den Inhalt Ihrer Dropdown / Popover.

Eine andere Möglichkeit, diese aufzunehmen, um die Reaktionskomponente aufzunehmen, die Sie in der Renderfunktion des Popover-Inhalts in der Render-Funktion des Popovers (dh 'die Seite') enthalten möchten"Das wird also nicht angezeigt und nimmt keinen Platz an, geben Sie ihm auch eine ID, z.'popovercontent'.Wenn Sie dann den Popover-Set-Inhalt initialisieren: document.getelementbyId ("popovercontent").Im Bootstrap 4 zumindest nimmt es ein Element als Inhalt an.

Sie müssen den Bootstrap-Code nicht auf diese Weise ändern, wodurch Wartung / Updates einfacher ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top