在 Bootstrap 弹出窗口中渲染 React 组件
-
21-12-2019 - |
题
我有一组在内容属性/参数中使用 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 的 renderComponentToString
它接受一个组件并通过回调返回一个 HTML 字符串:
var html = React.renderComponentToString(<MusicList />);
$(this.getDOMNode()).popover({
html: true,
content: html
});
但是,如果您的组件具有任何交互性,则该策略将不起作用,因为 React 永远没有机会附加事件处理程序(或运行任何自定义生命周期方法)。事实上,Bootstrap 没有提供适当的挂钩来使您的弹出窗口内容动态化。
也就是说,可以通过修补 Bootstrap 来实现此目的。我创建了一个具有动态弹出内容的现场演示:
http://jsfiddle.net/spicyj/q6hj7/
请注意,当前时间由每秒更新的 React 组件在弹出窗口中呈现。
这个弹出窗口是如何创建的?
我打了补丁 Bootstrap 弹出窗口 setContent
方法 除了 HTML 或文本字符串之外,还可以使用 React 组件。而不是使用 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 调用,包括从 DOM 中删除包装器组件后正确清理弹出窗口组件。
其他提示
有一个名为React-Bootstrap的新库,正在进行快速开发。
https://reacont-bootstrap.github.io/components.html#popover
如果您包含此模块,您可以使用可以在变量中保存的POLPOVER成为其自己的组件,然后在渲染功能中使用。
React.Render(SouriterInstance,MountNode);
var popOver = (
<Popover>
<table>
{
columns.map(col =>
<tr>
<td style={{textAlign:'right', padding:5}}>
{col.label}:
</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,用户无法更改月份,而无需重新打开菜单以选择新日期)。
我有同样的问题,我提出了一个简单又替代的解决方案。
我不想使用React-Bootstrap(我的应用程序的其他部分没有acctfifed并使用引导,所以我不想有两个库做同样的事情)。
通过Bootstrap从框中提供的下拉组件几乎提供了与Popover相同的功能,除了它更灵活。 这是标准引导下拉下降:
<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>
.
以下是您需要在不破坏它的情况下使其工作的最小值,并且您可以在其中包含其中的任何反应元素:
<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)下拉列表上的“下拉菜单”(您也可以将其更改为您想要的任何HTML元素,并且您不必粘贴引导程序提出的“UL”元素)。
与popover相比,松散了一些功能(你无法定义自己的转换,你不能在顶部,左或右上显示它们,但仅在下面 - 它是一个下拉目),但您可以获得对内容的总控制你的下拉/弹出。
解决此解决方案以包括要在包含POPOVER(即“页面”的组件的渲染函数中的开发组件中的反应组件(即“)”,但将其放在带有样式的DIV中的渲染函数中“因此,没有显示并占用空间,也给它一个ID,例如,'popovercontent'。然后,当您初始化Popover Set内容:Document.getElementByID(“PopoverContent”)。在Bootstrap 4中至少,它需要一个元素作为内容。
您不需要以这种方式修改引导码,使维护/更新更容易。