Вопрос:

Рендеринг компонента React в поповере Bootstrap

jquery twitter-bootstrap reactjs

11593 просмотра

4 ответа

148 Репутация автора

У меня есть набор изображений, в которых есть всплывающие окна, использующие компонент 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} />

                );
    }
});
Автор: Fredrick Thornton Источник Размещён: 17.11.2013 05:01

Ответы (4)


39 плюса

96197 Репутация автора

Решение

Bootstrap не позволяет легко визуализировать динамический компонент в поповере. Если всплывающее окно, которое вы хотите представить, является статическим, вы можете просто использовать React, renderComponentToStringкоторый берет компонент и возвращает строку HTML через обратный вызов:

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

Однако, если у вашего компонента есть какая-либо интерактивность, эта стратегия не сработает, потому что React никогда не имеет возможности присоединять обработчики событий (или запускать какие-либо из ваших пользовательских методов жизненного цикла). Действительно, Bootstrap не предоставляет надлежащих хуков, чтобы сделать ваш контент поповерным динамичным.


Тем не менее, это можно сделать, исправив Bootstrap. Я создал живую демоверсию с динамическим поповерным контентом:

демоверсия поповера
http://jsfiddle.net/spicyj/q6hj7/

Обратите внимание, что текущее время отображается во всплывающем окне компонентом React, который обновляется каждую секунду.


Как был создан этот поповер?

Я исправил метод Popover в Bootstrap,setContent чтобы взять компонент React в дополнение к HTML или текстовой строке. Вместо того, чтобы использовать jQuery 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, включая правильную очистку компонентов popover после удаления компонента оболочки из DOM.

Автор: Sophie Alpert Размещён: 17.11.2013 08:47

2 плюса

84 Репутация автора

Существует новая библиотека под названием 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);

мой код:

showMoreDetails: function (obj, columns) {

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

},
Автор: ml242 Размещён: 28.09.2015 05:54

0 плюса

283 Репутация автора

После публикации этого ответа, тестирования и небольшой работы с этим обходным путем я понимаю, что он не оптимален.

Раскрывающиеся меню начальной загрузки закрываются, как только с ним взаимодействует пользователь. Это может быть нежелательным поведением (в моем случае я вставляю указатель даты, и пользователь не может изменить месяц без повторного открытия меню для выбора новой даты).


У меня была та же проблема, и я нашел простое и альтернативное решение.

Я не хотел использовать response-bootstrap (другие части моего приложения не реактифицированы и используют bootstrap, поэтому я не хочу, чтобы две библиотеки делали одно и то же).

Компонент раскрывающегося списка, предоставляемый из коробки Bootstrap, почти обеспечивает те же функции, что и всплывающее окно, за исключением того, что он более гибкий. Это стандартный выпадающий список 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>

Вот минимум, который вам нужен, чтобы он работал, не нарушая его, и вы можете включить в него любой элемент React:

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

Все, что вам нужно сохранить, это (i) класс «выпадающий» в div-обертке, (ii) атрибут переключателя данных «выпадающий» в триггере (вы можете изменить свой триггер на любой HTML-элемент, который вы хотите) и (iii) класс «dropdown-menu» в выпадающем меню (вы также можете изменить его на любой элемент html, который вам нужен, и вам не нужно вставлять элемент «ul», предложенный Bootstrap).

Вы теряете несколько функций по сравнению с поповером (вы не можете определить свои собственные переходы, вы не можете отображать их сверху, слева или справа, но только ниже - это выпадающий список), но вы получаете полный контроль над содержимым выпадающего списка. /трещать.

Автор: Cedric Размещён: 14.01.2016 08:38

0 плюса

728 Репутация автора

Другой способ решить эту проблему - включить компонент реагирования, который вы хотите использовать в качестве содержимого всплывающего окна, в функцию рендеринга компонента, содержащего всплывающее окно, но поместить его в элемент div со стилем «display: none;» так что это не отображается и не занимает места, также дайте ему идентификатор, например, «popOverContent». Затем при инициализации содержимого набора всплывающих окон: document.getElementById ("popOverContent").

Автор: Skill M2 Размещён: 29.01.2019 11:08
Вопросы из категории :
32x32