我们在JBoss 7.1上构建了一个基于 JSF2 和Primefaces 3.3的Web应用程序。
在我们的某个页面上,有一个ui:repeat
显示10个项目;然后用户可以点击某种“显示更多”按钮,并通过ajax显示另外10个项目。用户可以单击“显示更多”按钮,直到没有更多项目显示。注意:这不是分页,每次点击“显示更多”时显示的列表会变长。
实际上,当用户点击按钮时,服务器返回旧项和新项,而JSF的客户端每次都必须通过jQuery重建整个转发器。
我们希望找到更好,更高效的解决方案。旧项目在 n-1 和 n 调用之间不会发生变化,因此如果服务器只能通过ajax返回10个新项目,那么效率会更高。
JSF2有可能吗? JSF似乎并不真正符合这种递归渲染。唯一可以帮助我们的组件是TreeNode组件,但它看起来有点像黑客: - /
答案 0 :(得分:10)
标准的JSF API中没有类似的东西。 在PrimeFaces中也没有任何想法。对于PrimeFaces,最后看到更新
OmniFaces <o:componentIdParam>
可能正是您正在寻找的。它允许您让JSF仅基于特定的请求参数呈现组件树的子集,该参数可以是组件ID或客户端ID。您基本上只需使用jQuery的$.get()
重新加载<ui:repeat>
以及起始索引作为请求参数,并使用jQuery的$.append()
将其附加到HTML DOM。
这是一个完整的启动示例。观点:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:o="http://omnifaces.org/ui"
>
<f:metadata>
<o:componentIdParam componentIdName="componentId" />
</f:metadata>
<h:head>
<title>Stack Overflow Question 11364006</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script> <!-- Substitute with PrimeFaces' one, if necessary. -->
</h:head>
<h:body>
<ul id="items">
<ui:repeat id="itemsRepeater" value="#{bean.items}" var="item">
<li>#{item}</li>
</ui:repeat>
</ul>
<input type="button" id="showMore" value="Show more"/>
<h:outputScript>
$("#showMore").click(function() {
$items = $("#items");
var params = { start: $items.find("li").length, componentId: "itemsRepeater" };
$.get(location, params, function(html) {
$items.append(html);
});
});
</h:outputScript>
</h:body>
</html>
支持bean:
@ManagedBean
@RequestScoped
public class Bean {
private List<String> items;
@ManagedProperty("#{param.start}")
private int start;
@PostConstruct
public void init() {
// Just a stub. Do your thing to fill the items.
items = new ArrayList<String>();
int size = start + 10;
for (int i = start; i < size; i++) {
items.add("item " + (i + 1));
}
}
public void setStart(int start) {
this.start = start;
}
public List<String> getItems() {
return items;
}
}
更新:可以在the <o:componentIdParam>
page of current showcase application的“展开式列表”示例中找到实时演示。
更新2):PrimeFaces p:datascroller
有lazyloading with 'on demand scrolling'
答案 1 :(得分:1)
对于这样的情况,我完全绕过JSF并使用JQuery-RS服务和jQuery AJAX。这种方法将帮助您构建比JSF的AJAX支持更好的应用程序。这是基本技术。
在XHTML页面中,只需拥有列表的占位符:
<div id="item_list"></div>
<a href="#" onclick="loadNext();">Load more...</a>
当页面加载时,发出一个AJAX请求来填充初始列表。这是示例代码。可能存在拼写错误,但你明白了。
var nextStart = 0;
$(function() {
loadNext();
});
function loadNext() {
$.ajax({
type: "GET",
url: "api/items?start=" + nextStart,
success: function(data) {
appendToList(data);
nextStart += data.length;
}
});
}
function appendToList(data) {
//Iterate through data and add to DOM
for (var i = 0; i < data.length; ++i) {
$("#item_list").append($("<p>", {text: data.productName}));
}
}