我正在使用JSF 2.0和Primefaces 3.2开发应用程序,遇到了以下问题:如果内容是使用 ajax 请求动态加载的,则不会调用操作侦听器。
主要布局:
<div id="content">
<h:form name="content_form" id="content_form">
<ui:insert name="content" />
</h:form>
</div>
索引页(内容根据菜单操作动态加载(:
<ui:composition template="layout.xhtml">
<ui:define name="content">
<ui:include src="#{ajaxViewBean.viewName}" />
</ui:define>
</ui:composition>
菜单操作的生成方式如下:
FacesContext context = FacesContext.getCurrentInstance();
MethodExpression methodExpression = context
.getApplication()
.getExpressionFactory()
.createMethodExpression(
context.getELContext(),
"#{ajaxViewBean.setViewName('" + navItem.getUrl()
+ "')}", null,
new Class[] { ActionEvent.class });
displayMenuItem.setUpdate(":content_form");
displayMenuItem
.addActionListener(new MethodExpressionActionListener(
methodExpression));
单击菜单项后,它调用AjaxViewBean"请求范围"来设置当前视图页面并更新主布局中的"content_form">
包含的页面(其中操作侦听器不起作用(
首次尝试 - 文件上传(上传文件.xhtml(
<h:body> <h:form enctype="multipart/form-data"> <p:fileUpload fileUploadListener="#{fileUploadController.handleFileUpload}" mode="advanced" update="messages" multiple="true" sizeLimit="100000" allowTypes="/(.|/)(gif|jpe?g|png)$/"/> <p:growl id="messages" showDetail="true"/> </h:form>
文件上传控制器永远不会被调用。如果我直接请求上传文件.xhtml或者在第一次加载时将其包含在内,我可以上传文件,以便我确保上传是工作文件,并且在 web.xml 中正确配置了所有内容。
第二次尝试 - 包含页面中的菜单操作侦听器
<h:body> <h:form> <p:menu type="tiered" style="width:180px"> <p:submenu label="Ajax Menuitems" icon="ui-icon-refresh"> <p:menuitem value="Save" actionListener="#{ajaxViewBean.setViewName()}" update="messages" icon="ui-icon-disk" /> <p:menuitem value="Update" actionListener="#{buttonBean.update}" update="messages" icon="ui-icon-arrowrefresh-1-w" /> </p:submenu> </p:menu> </h:form>
此外,动作侦听器中的事件永远不会触发,尽管它在主页中触发,并且是从上面提到的代码动态生成的
Maven 依赖:
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.sun.facelets</groupId>
<artifactId>jsf-facelets</artifactId>
<version>1.1.14</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>el-impl</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>3.2</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.3</version>
</dependency>
如果我错过了什么,有人可以请我建议,或者我该如何解决这个问题?
实际上这是我在 Stackoverflow 中的第一篇文章,所以我希望我把自己说清楚并且格式不会乱七八糟
已修复!,我正在发布答案(也许对某人有用(步骤如下:
- 确保没有违反此 URL:命令按钮/命令链接/ajax 操作/侦听器方法未调用或输入值未更新
-
根据以下 URL 使用部分状态保存方法为假:http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html
<context-param> <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name> <param-value>false</param-value> </context-param>
需要强调的是:
- 但是,全局禁用部分状态保存的缺点是视图状态大小会增大。因此,如果您使用的是服务器端状态保存方法,则服务器的内存使用量将增加,或者如果您使用的是客户端状态保存方法,则网络带宽使用量将增加。基本上,您获得的视图状态信息与 JSF 1.x 中相同。如果可能,您还可以通过 web 中的以下上下文参数禁用按视图保存部分状态.xml
正如我所看到的,您正在嵌套表单。这在 HTML/XHTML 中是不允许的。
您有封闭的content_form
,包含页面也各有一个表单。
尝试删除content_form
:
<div id="content">
<ui:insert name="content" />
</div>
并更改displayMenuItem
以将更新设置为div content
:
displayMenuItem.setUpdate(":content");
我希望它有所帮助。