سؤال

لدي مجموعة من الصور التي تحتوي على عناصر منبثقة تستخدم مكون bootstrap popover ui في سمة/معلمة المحتوى وأود إضافة مكون ReactJS MusicList ولكن لم أتمكن من معرفة بناء الجملة أو ما إذا كان ذلك ممكنًا أم لا.

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

                );
    }
});
هل كانت مفيدة؟

المحلول

لا يجعل Bootstrap من السهل عرض مكون ديناميكي داخل النافذة المنبثقة.إذا كان العنصر المنبثق الذي تريد تقديمه ثابتًا، فيمكنك ببساطة استخدام React's renderComponentToString الذي يأخذ مكونًا ويعيد سلسلة من HTML من خلال رد اتصال:

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

ومع ذلك، إذا كان المكون الخاص بك يحتوي على أي تفاعل، فلن تعمل هذه الإستراتيجية لأن React لن يكون لديها فرصة أبدًا لإرفاق معالجات الأحداث (أو تشغيل أي من أساليب دورة الحياة المخصصة الخاصة بك).في الواقع، لا يوفر Bootstrap الروابط المناسبة لجعل المحتوى المنبثق ديناميكيًا.


ومع ذلك، من الممكن إنجاز هذا العمل عن طريق تصحيح Bootstrap.لقد قمت بإنشاء عرض توضيحي مباشر يحتوي على محتوى منبثق ديناميكي:

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

لاحظ أن الوقت الحالي يتم عرضه داخل العنصر المنبثق بواسطة مكون React الذي يتم تحديثه كل ثانية.


كيف تم إنشاء هذا البوبوفر؟

أنا مصححة Bootstrap Popover setContent طريقة لأخذ مكون React بالإضافة إلى HTML أو سلسلة نصية.بدلاً من استخدام jQuery's html أو text الأساليب التي أستخدمها 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]);
    }
};

الآن أصبح بإمكانك الكتابة

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

في الخاص بك componentDidMount الطريقة وتقديمها بشكل صحيح.إذا نظرت إلى JSFiddle المرتبط، فسترى غرضًا عامًا <BsPopover /> المُجمِّع الذي قمت بإنشائه والذي يعتني بجميع استدعاءات Bootstrap نيابةً عنك، بما في ذلك تنظيف المكونات المنبثقة بشكل صحيح بمجرد إزالة مكون المُجمِّع من DOM.

نصائح أخرى

هناك مكتبة جديدة تسمى React-Bootstrap والتي تخضع للتطوير السريع.

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

إذا قمت بتضمين هذه الوحدة، فستكون لديك القدرة على جعل العنصر المنبثق مكونًا خاصًا به يمكنك حفظه في متغير ثم استخدامه في وظيفة العرض الخاصة بك.

مثالهم:

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

رمز بلدي:

عرض مزيد من التفاصيل:وظيفة (الكائنات، الأعمدة) {

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

},

بعد نشر هذا الرد وبعد اختباره وعمل قليلا مع هذا العمل حول هذا العمل، أدرك أنه ليس الأمثل.

القوائم المنسدلة bootstrap تغلق بمجرد أن تفاعل المستخدم معها. قد لا يكون هذا السلوك المرغوب فيه (في حالتي، فأنا أدرج DatePicker ولا يمكن للمستخدم تغيير الشهر دون الحاجة إلى إعادة فتح القائمة لاختيار تاريخ جديد).


كان لدي نفس المشكلة وتوصلت إلى حل سهل وبديل.

لم أكن أرغب في استخدام رد الفعل-bootstrap (لا يتم الرد على أجزاء أخرى من التطبيق الخاص بي واستخدام bootstrap، لذلك لا أريد أن يكون لديك مكتبتين يفعلان نفس الشيء).

مكون المنسدلة المنصوص عليها من الصندوق من قبل Bootstrap توفر تقريبا نفس الوظائف مثل Popover، إلا أنها أكثر مرونة. هذا هو المنسدلة Bootstrap القياسية:

giveacodicetagpre.

هنا هو الحد الأدنى الذي تحتاجه لجعله يعمل دون كسره ويمكنك تضمين أي عنصر من رد الفعل داخله:

giveacodicetagpre.

كل ما تحتاجه للحفاظ عليه هو (ط) الفئة "المنسدلة" على المجمع DIV، (II) سمة البيانات "المنسدلة" على الزناد (يمكنك تغيير الزياد الخاص بك إلى أي عنصر HTML الذي تريده) و (III) "القائمة المنسدلة" من الفئة على القائمة المنسدلة (يمكنك أيضا تغييرها إلى أي عنصر HTML الذي تريده ولن تضطر إلى التمسك بعنصر "UL" المقترح بواسطة Bootstrap).

أنت تفقد بعض الميزات القليلة مقارنة ب Popover (لا يمكنك تحديد التحولات الخاصة بك، ولا يمكنك عرضها على القمة أو اليسار أو اليمين، ولكن أدناه فقط - إنها منسدلة) لكنك تكسب التحكم الكلي عبر المحتوى من القائمة المنسدلة / popover الخاص بك.

طريقة أخرى لحل هذا لتضمين مكون المتفاعل الذي تريد أن تكون محتوى Popover في وظيفة Render للمكون الذي يحتوي على Popover (أي الصفحة ") ولكن ضعه داخل DIV مع نمط" عرض: لا شيء؛"بحيث لا يتم عرضها واتخاذ أي مساحة، قم أيضا بإعطائها معرفا، على سبيل المثال"popolovontentent".ثم عند تهيئة محتوى ضبط محتوى Popover: Document.getelementByID ("popovercontent").في Bootstrap 4 على الأقل، يستغرق عنصر كمحتوى.

لا تحتاج إلى تعديل رمز bootstrap بهذه الطريقة، مما يجعل الصيانة / التحديثات أسهل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top