【发布时间】:2017-09-17 14:17:30
【问题描述】:
我正在使用 JSF 构建一个单页应用程序,看起来像这样:
左侧的菜单是动态生成的,单击其中一个子菜单会创建一个选项卡,我在其中显示来自 <ui:include> 的内容。
菜单和选项卡代码:
<p:layoutUnit position="west" resizable="false" size="210">
<h:form id="menu_form">
<p:panelMenu style="width:200px" model="#{homeView.menu}" />
</h:form>
</p:layoutUnit>
<p:layoutUnit id="center-layout" position="center">
<p:tabView id="tabss" style="font-size: 15px"
activeIndex="#{homeView.index}" scrollable="true">
<p:ajax event="tabClose" listener="#{homeView.onTabClose}"
update="tabss" />
<p:ajax event="tabChange" listener="#{homeView.onTabChange}"
update="tabss" />
<c:forEach items="#{homeView.openTabs}" var="otab">
<p:tab title="#{otab.title}" closable="true"
style="font-size: 15px" rendered="#{otab.open}">
<p:scrollPanel mode="native" styleClass="scrollPanels">
<ui:include src="#{otab.content}" />
</p:scrollPanel>
</p:tab>
</c:forEach>
</p:tabView>
</p:layoutUnit>
主页的支持 bean:
@ManagedBean
@ViewScoped
public class HomeView {
private List<Tab> tabs;
private List<Tab> openTabs;
private int index;
private TabService tabService;
private MenuService menuService;
private MenuModel menu;
@ManagedProperty("#{loginView}")
private LoginView loginView;
@PostConstruct
public void init() {
tabService = new TabService();
menuService = new MenuService();
tabs = menuService.loadTabs(loginView.getUtilisateur().getProfile());
openTabs = new ArrayList<Tab>();
menu = menuService.loadMenu(loginView.getUtilisateur().getProfile());
}
public void addTab(String title) {
if (tabService.check(openTabs, title)) {
openTabs = tabService.addTab(tabs, openTabs, title);
}
if (tabService.getIndex(openTabs, title) != -1) {
index = tabService.getIndex(openTabs, title);
}
}
public void onTabClose(TabCloseEvent event) {
String title = event.getTab().getTitle();
String ti = openTabs.get(index).getTitle();
openTabs = tabService.closeTab(openTabs, title);
if (ti.equals(title)) {
index = tabService.setIndex(index);
} else {
index = tabService.setIndex(openTabs, ti);
}
}
public void onTabChange(TabChangeEvent event) {
index = tabService.getIndex(openTabs, event.getTab().getTitle());
}
// Getters and setters
我应该注意,单击子菜单会调用addTab(Title) 方法来打开选项卡
每个包含的页面(显示在选项卡中的页面)都使用自己的 viewscoped bean,该 bean 在关闭选项卡后被销毁(参见上面的代码)。
问题:
在上面的屏幕截图中,我显示了一个选项卡,其中我在 <p:dataTable> 中显示搜索结果,我想要的行为是:
每当从数据表中选择一个元素时,我都想打开一个选项卡,在其中显示有关该元素的更多信息。对我来说重要的是能够同时打开多个选项卡(显示有关元素的更多信息)。
我想到的是创建一个 xhtml 来完成显示部分,以及一个 viewscoped bean 来支持所述页面。那么有没有办法手动实例化所述bean(每次用户单击按钮)然后用相应的数据填充它,这样我就可以多次重复使用同一个页面?
谢谢
【问题讨论】:
-
为什么你需要元素信息页面作为一个信息显示页面进行viewscoped?除非您需要 viewscope ,否则您可以将其设置为 requestscoped ?
-
@OTM 从技术上讲,它不只是显示信息,我想在该页面中做的是:使用所选项目执行一些查询以获取要显示的数据(这将进入它的 init()方法),它会有一些命令按钮来执行更多的查询。使其 requestScoped 将允许它被多次实例化?
-
是的,对于 requestscoped bean,它将被实例化多次,每个信息页面请求具体一个实例化。即使您在信息页面中有命令按钮,只要您在请求范围内维护数据,进一步提交也应该与 requestscoped 一起使用。
-
我已经尝试过了,但只是更改选项卡算作请求并触发 bean 的销毁。因为在我的情况下,我想让 bean 保持活力,直到我关闭选项卡(正如我在问题中提到的那样)
-
好的。如果您想多次使用同一个视图,我认为您不能拥有同一个 bean 的多个 viewscoped 实例。作为一种解决方法,您可以为多个信息页面请求使用相同的 viewscoped bean。当您打开信息页面时,您可以传递标识符。例如,1,2 分别用于信息页面一和二,并通过标识符将任何关联数据存储在集合中,并相应地在页面中进行变量绑定。
标签: java jsf primefaces