18

JSF2とPrimefaces3.3を使用してJBoss7.1上に構築されたWebアプリケーションがあります。

私たちのページの1つに、ui:repeat10個のアイテムが表示されています。次に、ユーザーはある種の「もっと見る」ボタンをクリックすると、ajaxを介してさらに10個のアイテムが表示されます。表示するアイテムがなくなるまで、ユーザーは[もっと見る]ボタンをクリックできます。注:これはページネーションではありません。「もっと見る」をクリックするたびに、表示されるリストが長くなります。

実際、ユーザーがボタンをクリックすると、サーバーは古いアイテムと新しいアイテムを返し、JSFのクライアント側は毎回jQueryを介してリピーター全体を再構築する必要があります。

より優れた、よりパフォーマンスの高いソリューションを見つけたいと考えています。古いアイテムはn-1呼び出しとn呼び出しの間で変更されないため、サーバーがajaxを介して10個の新しいアイテムのみを返すことができればより効率的です。

JSF2で可能ですか?JSFは、この種の再帰的レンダリングに実際には準拠していないようです。おそらく私たちを助けることができる唯一のコンポーネントはTreeNodeコンポーネントですが、それはちょっとしたハックのようです:-/

4

2 に答える 2

10

標準の JSF API にはそのようなものはありません。また、PrimeFaces では何も思い浮かびません。PrimeFaces については、最後の更新を参照してください

ただし、OmniFaces <o:componentIdParam>はまさにあなたが探しているものかもしれません。コンポーネント ID またはクライアント ID などの特定のリクエスト パラメータに基づいて、コンポーネント ツリーのサブセットのみを JSF にレンダリングさせることができます。基本的には、jQuery を使用して開始インデックスをリクエスト パラメータとして$.get()リロードし、 jQuery を使用してそれを HTML DOM に追加することができます。<ui:repeat>$.append()

完全なキックオフの例を次に示します。景色:

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

}

更新: ライブ デモは、現在のショーケース アプリケーション<o:componentIdParam>ページの「展開可能なリスト」の例にあります。

更新 2) : PrimeFacesp:datascrollerには「オンデマンド スクロール」による遅延読み込みがあります

于 2012-08-14T16:15:11.913 に答える
1

このような状況では、JSFを完全にバイパスし、jQueryAJAXでJAX-RSサービスを使用します。このアプローチは、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}));
    }
}
于 2012-08-15T18:39:34.177 に答える