2015-07-02 55 views
1

我正在嘗試使用LazyDataModel向<p:dataScroller>提供未知數量的項目。我從存儲中讀取它們(來自用戶交互),然後將所需數量發送回模型。Primefaces LazyDataModel具有未知數量的項目拋出IllegalArgumentException

該項目有一個結束,但我不知道數量,直到我讀它們全部,所以我設置在DataModel 1,000個項目的上限。

負載()的示範實施:

@Override 
public List<MyPojo> load(int first, int pageSize, String sortField, 
     SortOrder sortOrder, 
     Map<String, Object> filters) { 
    return managedBean.loadMoreItens(first, pageSize); 
} 

而且loadMoreItens(int, int)

List<MyPojo> loadMoreItens(int first, int pageSize) { 

    int amountLoaded = 0; 
    while(first+pageSize > this.list.size()) { 
     if (this.endReached) { 
      break; 
     } 
     amountLoaded++; 
     list.add(readNewItem()); //readNewItem sets boolean if it reaches the end. 
    } 
    int end = first + pageSize; 

    // do some other unrelated stuff like logging and such. 

    return list.subList(first, Math.min(end, list.size())); 
} 

它工作正常,加載chunkSize itens每次用戶滾動元件(所以我會跳過在這裏發佈JSF),但當到達最後時,拋出一個令人討厭的異常:

Jul 02, 2015 10:58:51 AM com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback visit 
SEVERE: java.lang.IllegalArgumentException: fromIndex(380) > toIndex(371) 

380/371這裏的數字是隨機產生的測試質量,所以數量可能會有所變化。問題是要達到的項目的結束,但模型仍然認爲有少於1,000。

如何避免拋出異常?

P.S:

  1. 的項目不來從數據庫中。在沒有獲取所有項目的情況下,無法通過「輕查詢」來了解數量。
  2. 獲取新物品的過程非常昂貴(不能說出它們是什麼),除非需要,否則不應該這樣做。
  3. managedBean初始化爲前20項,即需求規格。可以有數百或數十個。有1000件天花板。
  4. 託管bean試圖在初始化lazyModel之前獲得20個itens,所以如果少於20個項目,我可以設置金額正確但小於0.1%的情況。
+0

你應該像之前計數的項目一樣,至少只是第一次如果它是空的... –

+0

@HatemAlimam它不是一個數據庫查詢 - 數量是真正未知的,直到我全部閱讀 - 並且獲得這些物品的成本相當高,所以整個問題只會在需求時加載它們。我根據需求規格初始化了前20項的managedBean。 – Mindwin

+0

該組件依賴於設計計數,你最好的辦法就是捕捉那個異常... –

回答

1

正如@Kukeltje指出的那樣,PF項目負責人已將其標記爲new-feature,因此直到Primefaces發佈該功能後纔會有解決方案。

https://code.google.com/p/primefaces/issues/detail?id=5750

https://github.com/primefaces/primefaces/issues/51

的解決方法並沒有爲我工作,因爲這個問題是分頁DataTable和我使用的是dataScroller。

問題出在subList()命令;我只好兩個指數限制在list.size()

List<MyPojo> loadMoreItens(int first, int pageSize) { 

    int amountLoaded = 0; 
    while(first+pageSize > this.list.size()) { 
     if (this.endReached) { 
      break; 
     } 
     amountLoaded++; 
     list.add(readNewItem()); //readNewItem sets boolean if it reaches the end. 
    } 
    int end = first + pageSize; 

    // do some other unrelated stuff like logging and such. 

    return list.subList(Math.min(first,list.size()), Math.min(end, list.size())); 
} 

它跳過休息和避免異常,但負載控制不會從頁面消失。

然後我添加了一個javascript代碼來隱藏它,當通過remoteCommand到達末端時。

相關問題