【发布时间】:2011-08-08 05:44:11
【问题描述】:
这个例子有点极端,我想做的不完全是这个,而是更简单地证明我的问题
我有一个页面,有一个简单的 index.xhtml:
<html
xmlns:h="http://java.sun.com/jsf/html"
xmlns:mc="http://java.sun.com/jsf/composite/mc">
...
<h:panelGroup id="u1" styleClass="unique_container">
<mc:component1></mc:component1>
</h:panelGroup>
<h:panelGroup id="u2" styleClass="unique_container">
<mc:component2></mc:component2>
</h:panelGroup>
<h:panelGroup id="u3" styleClass="unique_container">
<mc:component3></mc:component3>
</h:panelGroup>
<form action="/faces/async.xhtml">
<input type="checkbox" name="renderu1" />
<input type="checkbox" name="renderu2" />
<input type="checkbox" name="renderu1" />
<input type="submit" value="render" />
</form>
...
</html>
当我按下“GO”按钮时,如果检查了 renderu1,我想渲染 component1,如果检查了 renderu2,我想渲染 component2,如果检查了 renderu3,我想渲染 component3
我目前的解决方案是使用 jQuery 表单插件的 js 函数:
$(document).ready(function(){
registerForms($(document));
});
function registerForms(rootElement)
{
rootElement.find("form").submit(function() {
// submit the form
$(this).ajaxSubmit(function(data, textStatus) {
if(textStatus == "notmodified")
return;
var tempDiv = $('<div></div>');
tempDiv.css("display", "none");
tempDiv.html(data);
var newUniqueContainer;
while((newUniqueContainer = tempDiv.find(".unique_container:first")).html() != null)
{
var oldUniqueContainer = $("#" + newUniqueContainer.attr("id") + ":first");
oldUniqueContainer.empty();
oldUniqueContainer.html(newUniqueContainer.html());
registerForms(oldUniqueContainer);
newUniqueContainer.remove();
}
tempDiv.remove();
});
// return false to prevent normal browser submit and page navigation
return false;
});
}
它的作用是每当我提交表单时,它会向给定的 url 触发一个 ajax 请求,等待响应,如果有内容(状态代码不是 304,所以它不是“未修改”),它会得到数据,并将原始“unique_containers”中的内容替换为新数据
async.xhtml:
<html xmlns:mc="http://java.sun.com/jsf/composite/mc"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<c:if test="#{asyncBean.render1}">
<h:panelGroup id="u1" styleClass="unique_container">
<mc:component1></mc:component1>
</h:panelGroup>
</c:if>
<c:if test="#{asyncBean.render2}">
<h:panelGroup id="u2" styleClass="unique_container">
<mc:component2></mc:component2>
</h:panelGroup>
</c:if>
<c:if test="#{asyncBean.render3}">
<h:panelGroup id="u3" styleClass="unique_container">
<mc:component3></mc:component3>
</h:panelGroup>
</c:if>
</html>
AsyncBean.java:
@ManagedBean(name="asyncBean")
@RequestScoped
public class AsyncBean {
@ManagedProperty(value="#{param.renderu1}")
private boolean render1;
@ManagedProperty(value="#{param.renderu2}")
private boolean render2;
@ManagedProperty(value="#{param.renderu3}")
private boolean render3;
private boolean isRender1() {
return render1;
}
private void setRender1(boolean render1) {
this.render1 = render1;
}
private boolean isRender2() {
return render2;
}
private void setRender2(boolean render2) {
this.render2 = render2;
}
private boolean isRender3() {
return render3;
}
private void setRender3(boolean render3) {
this.render3 = render3;
}
}
因此,例如,如果仅选中第三个复选框,则响应将如下所示:
<html>
<span id="u3" class="unique_container">
content of component3
</span>
</html>
它工作正常,而且很简单,但后来我开始将 RichFaces 用于我的一个组件 - 问题是,它使用 jQuery 的 $(document).ready(fn) 函数,当我重新加载部件时使用 RichFaces,它会中断(它是一个树组件,我无法打开节点)
我一直在寻找一种可行的解决方案,它可以做我的工作,但为兼容性问题做好了更好的准备(从技术上讲,我想根据参数决定要更新的部分,所以当呈现原始页面时,我还不知道要写什么来“执行”和“渲染”属性)
【问题讨论】: