我正在学习JSF 2,感谢我在这么短的时间里学到了很多东西.
我的问题是关于如何为我的所有JSF 2页面实现一个公共布局,并且每当我从另一个面板单击一个链接/菜单时,只有页面的内容部分不刷新整个页面.我使用Facelets方法它做了我想做的事情,除了每次我点击一个面板的链接(例如左面板的菜单项)时,整个页面都会刷新.我正在寻找的是一种只刷新页面内容部分的方法.为了说明这一点,我的目标是pagelayout.
没有发布我的代码,因为我不确定Facelets是否可以这样做.除了Facelets之外,还有其他方法更适合我的要求吗?
我知道我们不能重复在同一个视图树中我们拥有的任何组件的ID.
我有一个页面,其中包含某些条件的其他页面像这样......
<h:panelGroup rendered="#{bean.insertMode == 'SINGLE'}">
<ui:include src="_single.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{bean.insertMode == 'DOUBLE'}">
<ui:include src="_double.xhtml" />
</h:panelGroup>
Run Code Online (Sandbox Code Playgroud)
现在在这些页面中,我有"几乎"相同的组件层次结构(复杂)具有不同的操作行为(不仅方法调用,还有视图),例如:
_single.xhtml
<p:inputText id="fieldID" value="#{bean.value}" />
<p:commandLink actionListener="#{bean.singleAction()}" />
Run Code Online (Sandbox Code Playgroud)
_double.xhtml
<p:inputText id="fieldID" value="#{bean.value}" />
<p:commandLink actionListener="#{bean.doubleAction()}" />
Run Code Online (Sandbox Code Playgroud)
我的小例子工作正常,并按照预期渲染,但我得到了
java.lang.IllegalStateException: Component ID fieldID has already been found in the view.
我知道JSF会处理整个页面,即使它们没有被包含在内,这就是我得到这个例外的原因.
任何聪明的方法来解决这个问题,而无需更改包含页面内的组件的ID(虽然它的工作原理,但异常是烦人的,似乎有些不对劲).
我也不想用一些具有不同ID的容器组件来包装每个页面,因此它们将具有不同的FULL ID,如formId:fieldID,因为母版页也指这些组件中的这些组件!
我正在尝试切换显示一个页面的页面<rich:dataTable>.在我刚刚包含<ui:include>模板之前,它只会显示整个表格.
<ui:include src="../log/viewDlg.xhtml"/>
Run Code Online (Sandbox Code Playgroud)
现在我希望能够在网页上打开/关闭它.在页面上显示可能有一个按钮或链接.我怎样才能实现它?
更新1:由于一些奇怪的原因,我无法让它出现,这是我到目前为止基于反馈写的内容
视图:
<a4j:commandLink value="View"
action="#{bean.showview}" render="viewPanel"/>
<h:panelGroup id="viewPanel">
<h:panelGroup id="tableRenderPanel" rendered="#{bean.showPolicyView}">
<ui:include src="../log/viewDlg.xhtml"/>
</h:panelGroup>
</h:panelGroup>
Run Code Online (Sandbox Code Playgroud)
支持豆:
private boolean showPolicyView = false;
public void showView() {
showPolicyView = !showPolicyView;
}
public boolean isShowPolicyView(){
return showPolicyView;
}
Run Code Online (Sandbox Code Playgroud) 我已经看到这个问题在很多地方问了,但是没有一个得到适当的回答所以我决定再问一遍.所以,如果我有这个:如果我在A.xhtml和我
<ui:include src="B.xhtml">
<ui:param name="formId" value="awesome Id"/>
</ui:include>
Run Code Online (Sandbox Code Playgroud)
所以B.xhtml,我可以这样做
<h:outputText value="#{formId}"/>
Run Code Online (Sandbox Code Playgroud)
当我跑步时A.xhtml,我会看到awesome Id在屏幕上打印出来.但是,如何访问formId辅助bean中的值.我看里面FacesContext.getCurrentInstance().getAttributes(),FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap()我似乎无法找到它.为了更进一步,我尝试:
在里面B.xhtml,我现在有
<h:inputHidden id="hiddenFormId" value="#{formId}"/>
<h:outputText value="#{formId}"/>
Run Code Online (Sandbox Code Playgroud)
这个想法是,我可以访问的值formId的RequestParameterMap下键hiddenFormId.但是现在如果我有:
<h:form id="myForm">
<ui:include src="B.xhtml">
<ui:param name="formId" value="awesome Id"/>
</ui:include>
<a4j:commandButton render="myForm" value="My Button"/>
</h:form>
Run Code Online (Sandbox Code Playgroud)
如果我查看POST请求(在chrome或ff调试模式下),我会得到这个错误
<partial-response><error><error-name>class javax.faces.component.UpdateModelException</error-name><error-message><![CDATA[/B.xhtml @9,61 value="${formId}": /index.xhtml @27,61 value="awesome Id": Illegal Syntax for Set Operation]]></error-message></error></partial-response>
那么如何在托管bean中访问ui:param值?
我有一个模板,它是编辑某些元素的表单的一部分。要执行的操作因包含它的页面而异。所以我将 action 方法作为参数传递:
<ui:param name="option" value="#{someOptionBean}" />
...
<ui:include src="/WEB-INF/jsf/value-edit.xhtml">
<ui:param name="controllerParam" value="#{optionController}" />
<ui:param name="elementParam" value="#{option}" />
<ui:param name="actionParam" value="updateOption" />
</ui:include>
Run Code Online (Sandbox Code Playgroud)
或者:
<ui:param name="property" value="#{somePropertyBean}" />
...
<ui:include src="/WEB-INF/jsf/value-edit.xhtml">
<ui:param name="controllerParam" value="#{propertyController}" />
<ui:param name="elementParam" value="#{property}" />
<ui:param name="actionParam" value="updateProperty" />
</ui:include>
Run Code Online (Sandbox Code Playgroud)
并且value-edit.xhtml有一个命令按钮:
<p:commandButton value="Update" action="#{controllerParam[actionParam](elementParam)}" />
Run Code Online (Sandbox Code Playgroud)
到目前为止一切正常。
我的问题是现在操作方法没有相同数量的参数。他们是:
public void updateOption(Option option) { ... }
public void updateProperty(Item item, Prop property) { ... }
Run Code Online (Sandbox Code Playgroud)
所以我现在希望能够定义动作参数以具有以下内容:
<ui:param name="actionParam" value="updateOption(option)" />
<ui:param name="actionParam" value="updateProperty(item, property)" />
Run Code Online (Sandbox Code Playgroud)
或类似的东西: …
ui:include标签是如何实现的?我在哪里可以找到它的实现(源代码)?
我想<ui:include>动态地多次包含一个页面.
码:
<h:dataTable ..>
<h:column>
<ui:include src="#{create_page}">
<h:column>
<h:dataTable>
Run Code Online (Sandbox Code Playgroud)
现在,当我提交它时,它只持续最后一个.它只记住最后一个包含页面的值.我想在每个create_page中使用唯一的实体对象.我怎样才能做到这一点?
我有一个页面,动态地包含来自另一个页面的内容(这是通过bean中的方法完成的)
firstPage.xhtml
<ui:include src="#{managedBean.pageView}">
<ui:param name="method" value="#{managedBean.someAction}"/>
</ui:include>
Run Code Online (Sandbox Code Playgroud)
这会重定向到第二个页面,<ui:composition>其中包含commandButton.
secondPage.xhtml
<ui:composition>
..
..
<p:commandButton actionListener=#{method} value="Submit"/>
</ui:composition>
Run Code Online (Sandbox Code Playgroud)
ManagedBean
public String pageView(){
return "secondPage.xhtml";
}
public void someAction(){
*someAction*
}
Run Code Online (Sandbox Code Playgroud)
secondPage.xhtml中的commandButton不起作用.
任何帮助将不胜感激.
我尝试在不同的选项卡中使用ui:include标记包含多个源页面路径.问题是当我将源页面路径视为静态时,意味着将显示页面,但如果从支持bean提供源页面路径意味着它将不包括页面.
这是我的代码
template.xhtml:
<p:layoutUnit position="center" id="layoutCenter">
<h:form id="tempFormId">
<p:tabView value="#{multiTabBean.tabsList}" var="useCase"
activeIndex="#{multiTabBean.activeTabIndex}">
<p:tab title="#{useCase.title}" closable="true">
<f:subview>
<h:panelGroup id="mainTempPanelGroupId" layout="block">
<ui:include src="#{useCase.path}" />
</h:panelGroup>
</f:subview>
</p:tab>
</p:tabView>
</h:form>
</p:layoutUnit>
Run Code Online (Sandbox Code Playgroud)
豆:
public String menuAction() {
menuBtnRendered = true;
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
selectedModuleViewId = externalContext.getRequestParameterMap().get(
"moduleViewId");
tabsList.add(new Tab(getTabId(selectedModuleViewId),
selectedModuleViewId, getModulePath(selectedModuleViewId)));
return null;
}
Run Code Online (Sandbox Code Playgroud)
我正在使用@ViewScoped.
我正在使用<ui:include>加载数据表(我正在使用Primefaces).我想<ui:param>在listener标签中使用<p:ajax>.我测试了关闭的代码,但没有触发事件onRowEdit或onRowCancel.这是我的页面:
...
<ui:include src="../Componentes/tablaEditable.xhtml">
<ui:param name="columnas" value="#{tabla2FuentesHL7.dataTableColumns}" />
<ui:param name="bean" value="#{tabla2FuentesHL7.listTabla2FuenteDTO}" />
<ui:param name="aceptarEdicion" value="#{tabla2FuentesHL7.onRowEdit}" />
<ui:param name="cancelarEdicion" value="#{tabla2FuentesHL7.onRowCancel}" />
</ui:include>
...
Run Code Online (Sandbox Code Playgroud)
我的数据表:
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:form >
<p:dataTable value="#{bean}" scrollable="true" scrollHeight="100" var="dato" editable="true">
<p:ajax event="rowEdit" listener="#{aceptarEdicion}" />
<p:ajax event="rowEditCancel" listener="#{cancelarEdicion}" />
<c:forEach items="#{columnas}" var="column" varStatus="loop">
<p:column headerText="#{column.header}" sortBy="#{dato[column.property]}">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{dato[column.property]}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{dato[column.property]}" style="width:100%" />
</f:facet>
</p:cellEditor> …Run Code Online (Sandbox Code Playgroud) 我是JSF的新手,我正在努力动态地渲染包含的页面。我的代码如下所示:
菜单豆
@ViewScoped
public class MenuBean implements Serializable {
private MenuItem[] menuItems = new MenuItem[] {
new MenuItem("page_1", "/page_1.xhtml"),
new MenuItem("page_2", "/page_2.xhtml"),
};
private String selectedItemLabel;
//...
}
Run Code Online (Sandbox Code Playgroud)
菜单项
public class MenuItem implements Serializable {
private String label;
private String page;
//...
}
Run Code Online (Sandbox Code Playgroud)
index.xhtml
<ui:repeat var="menuItem" value="#{menuBean.menuItems}">
<h:panelGroup rendered="#{menuBean.selectedItemLabel eq menuItem.label}" layout="block">
<h:outputText value="#{menuBean.selectedItemLabel}" />
<ui:include src="#{menuItem.page}" />
</h:panelGroup>
</ui:repeat>
Run Code Online (Sandbox Code Playgroud)
结果是渲染了2个按钮。每当我单击任何按钮时,都有条件渲染的panelGroup内部的标签会出现,但包含的页面却不会。如果我从第一个ui:repeat更改'menuItem1'var,它可以工作,但实际上是不可预测的。例如,如果我将setSelectedItemLabel参数硬编码为“ page_1”,则当我单击按钮_1时,将显示page_1,即使单击按钮_2,也会显示page_2(!?)。
我有一个主页xhtml,我根据条件包括3个孩子xhtml.我面临的问题是,无论情况如何,Book.xhtml总是被调用.我将渲染条件更改为false或移出到另一个条件,但始终调用该文件由于其调用其支持bean而导致不必要的开销.请给我一个解决方案
<ui:composition template="/xhtml/baseLayout.xhtml">
<ui:define name="browserTitle">
<h:outputText value="HOME PAGE" />
</ui:define>
<ui:define name="header">
<ui:include src="/xhtml/header.xhtml" />
</ui:define>
<ui:define name="bodyContent">
<h:panelGrid width="100%"
rendered="#{pogcore:isRoleAuthorized(BUNDLE.SUPER)}" >
<ui:include src="/xhtml/SuperUser.xhtml" />
</h:panelGrid>
<h:panelGrid width="100%"
rendered="#{pogcore:isRoleAuthorized(BUNDLE.MAINTENANCE)}" >
<ui:include src="/xhtml/Maintenance.xhtml" />
</h:panelGrid>
<h:panelGrid width="100%"
rendered="#{pogcore:isRoleAuthorized(BUNDLE.PRINT)}">
<ui:include src="/xhtml/Book.xhtml" />
</h:panelGrid>
</ui:define>
</ui:composition>
Run Code Online (Sandbox Code Playgroud) 我想通过使用<ui:repeat>和<p:dialog>使用创建动态对话框窗口<ui:include>.但是当我尝试下面的时候有一个例外.
main.xhtml
<p:outputPanel id="windowsPanel" layout="block" style="width:100%;">
<p:outputPanel rendered="#{mainView.dynamicWindows ne null}">
<ui:repeat var="item" value="#{mainView.dynamicWindows}">
<p:dialog binding="#{item.dialog}">
<ui:include src="#{item.includedWindowPath}" />
</p:dialog>
</ui:repeat>
</p:outputPanel>
</p:outputPanel>
Run Code Online (Sandbox Code Playgroud)
MainView.java
@ManagedBean(name = "mainView")
@SessionScoped
public class MainView extends BaseView {
private static final long serialVersionUID = -6291834350102049312L;
private List<Window> dynamicWindows;
@PostConstruct
public void init() {
fillWindows();
}
private void fillWindows() {
dynamicWindows = new ArrayList<Window>();
for (int i = 0; i < 3; i++) {
Window window = new Window("Header " …Run Code Online (Sandbox Code Playgroud) uiinclude ×13
jsf ×11
facelets ×6
jsf-2 ×6
primefaces ×2
uirepeat ×2
ajax-update ×1
conditional ×1
datatable ×1
dynamic ×1
el ×1
java ×1
jsf-1.2 ×1
jstl ×1
managed-bean ×1
param ×1
richfaces ×1
tabview ×1
xhtml ×1