我正在使用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)
来打开标签页
每个包含的页面(显示在选项卡中)都使用自己的视图结构bean,在关闭选项卡后将其销毁(参见上面的代码)。
有问题:
在上面的屏幕截图中,我展示了一个标签,我在<p:dataTable>
中显示搜索结果,我想要的行为是:
每当从dataTable中选择一个元素时,我想打开一个Tab,我将在其中显示有关所述元素的更多信息。对我来说重要的是能够同时打开多个Tab(显示有关元素的更多信息)
我想到的是创建一个将执行显示部分的xhtml,以及一个用于支持所述页面的视图结构bean。那么有没有办法手动实例化所述bean(每次用户点击按钮时),然后用相应的数据填充它,这样我可以多次重复使用同一页面?
感谢
答案 0 :(得分:1)
作为一种解决方法,您可以为多个信息页面请求使用相同的viewscoped bean。打开信息页面时,您可以将标识符作为参数传递。例如,1,2分别用于信息页面1和2,并通过标识符将任何相关数据存储在集合中,并相应地在页面中进行变量绑定。
答案 1 :(得分:0)
如果我很清楚你想要做什么,一种可能性就是以编程方式用视图作用域bean来评估表达式:
FacesContext context = FacesContext.getCurrentInstance();
ExpressionFactory expressionFactory = context.getApplication().getExpressionFactory();
ELContext elContext = context.getELContext();
ValueExpression vex = expressionFactory.createValueExpression(elContext, "#{viewBeanName}", ViewBeanClass.class);
ViewBeanClass viewBean = (ViewBeanClass) vex.getValue(elContext);
如果它不存在,那将会实例化bean,如果它确实存在,它将返回它。