How to partially reload a ui:repeat?

前端 未结 2 1599
清歌不尽
清歌不尽 2020-12-25 14:12

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 it

相关标签:
2条回答
  • 2020-12-25 14:54

    For situations like this, I completely bypass JSF and use JAX-RS service with jQuery AJAX. That approach will help you build much better applications than just the AJAX support from JSF. Here is the basic technique.

    In the XHTML page, simply have a placeholder for the list:

    <div id="item_list"></div>
    
    <a href="#" onclick="loadNext();">Load more...</a>
    

    When the page loads, make an AJAX request to populate the initial list. Here is sample code. There may be typos, but you get the idea.

    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}));
        }
    }
    
    0 讨论(0)
  • 2020-12-25 15:09

    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'

    0 讨论(0)
提交回复
热议问题