如何部分重载ui:repeat? [英] How to partially reload a ui:repeat?

查看:95
本文介绍了如何部分重载ui:repeat?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个基于JBoss 7.1, JSF2 和Primefaces 3.3的Web应用程序.

在我们的页面之一上,有一个ui:repeat显示10个项目;然后用户可以单击某种显示更多"按钮,并且通过ajax显示更多的10个项目.用户可以单击显示更多"按钮,直到没有更多要显示的项目为止.注意:这不是分页,每单击一次显示更多",显示的列表就会变长.

实际上,当用户单击按钮时,服务器将返回旧项目和新项目,并且JSF的客户端每次必须通过jQuery重建整个转发器.

我们想找到一个更好,更高效的解决方案.旧项目在 n-1 n 调用之间不会发生变化,因此如果服务器只能通过ajax返回10个新项目,则效率会更高.

在JSF2中可以吗? JSF似乎并不真正符合这种递归渲染.可能唯一可以帮助我们的组件是TreeNode组件,但这似乎有点hack:-/

解决方案

标准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>
 

后备豆:

 @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;
    }

}
 


更新:可以在当前展示应用程序的<o:componentIdParam>.

更新2):PrimeFaces p:datascroller具有

We've got a web application built on JBoss 7.1 with JSF2 and Primefaces 3.3.

On one of our page, there is a ui:repeat displaying 10 items; then the user can click on some kind of "show more" button and 10 more items are displayed through ajax. The user can click the "show more" button until there is no more items to show. Note: This is not pagination, the displayed list gets longer with each click on "show more".

In fact, when the user clicks on the button, the server returns the old items and the new ones, and the client side of JSF must rebuild the whole repeater through jQuery each time.

We would like to find a better and more performant solution. The old items don't change between the n-1 and the n call, so it would be more efficient if the server could only return through ajax the 10 new items.

Is it possible in JSF2 ? JSF seems not really compliant with this kind of recursive rendering. The only component that maybe could help us would be a TreeNode component, but it seems a bit of a hack :-/

解决方案

There's nothing like that in the standard JSF API. Also nothing comes to mind in PrimeFaces. For PrimeFaces see the update at the end

The OmniFaces <o:componentIdParam> may however be exactly what you're looking for. It allows you to let JSF render only a subset of the component tree based on a specific request parameter, which can be a component ID or a client ID. You could basically just use jQuery's $.get() to reload the <ui:repeat> along with the start index as a request parameter and use jQuery's $.append() to append it to the HTML DOM.

Here's a complete kickoff example. The view:

<!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>

The backing 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;
    }

}


Update: a live demo can be found in the "Expandable list" example of the <o:componentIdParam> page of current showcase application.

Update 2): PrimeFaces p:datascroller has lazyloading with 'on demand scrolling'

这篇关于如何部分重载ui:repeat?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆