簡體   English   中英

Primefaces數據表在列表上排序

[英]Primefaces datatable sort on list

我開始在項目中使用primefaces,但立即遇到問題。 我列出了一些我使用實體管理器從db獲取的東西,並在primefaces數據表的視圖中顯示了它。 在我的后備bean中,我具有:列表getList(),其中使用實體管理器從數據庫檢索記錄,並立即將其返回。

和myService:

public List<MyEntity> getDataList(){
  return entityManager.createNamedQuery("MyEntity.getAll").getResultList();
}

我的豆子:

public List<MyEntity> getList(){
  return myService.getDataList();
}

風景:

<p:dataTable var="myEntityInstance" value="#{myBean.list}"...

這種方式的primefaces排序不起作用,而且我在堆棧上的某個地方讀取到該列表需要成為我支持的bean的成員,我認為這很奇怪。這迫使我保持​​bean sessionScoped的作用,這不是很好的方法,因為服務器的內存會在整個會話中加載我的對象並使它們保持活動狀態,除此之外,保持列表更新還有更多開銷,因為每當我向視圖發出請求時,我都必須手動進行操作。 在@PostConstruct注釋方法中對該頁面的第一個請求時,將獲取我的列表。此后,我需要使其保持最新狀態。
我需要知道是否還有其他方法可以直接從db獲取列表並將其提供給primefaces而不將其保留在bean中? 到目前為止,我對primefaces所提供的功能並不滿意。.設計相當不錯,但是功能上存在很多錯誤。 我在其中的其他組件上也遇到類似的問題,並且發現較臟的修復程序,但它使我感到復雜而不是簡單。

除了編輯,

這里的問題是,每次對列表進行排序時,都會從實體中刷新列表。 由於在每次排序后UI每次刷新時都會建立框架,因此您要拉出一個新列表。

基本上,您會看到->(這並不准確,只是它在做什么)

  UI -> sort(myBean.getList());
  UI -> redraw(myBean.getList());

看這意味着您有兩個不同的引用,對引用#1進行排序,然后將其丟棄並獲得要渲染的新引用。 因此,您的排序不起作用。

解決方案是使用排序后可以引用的成員。 這不是一個大問題,因為您可以使用查看范圍而不是會話或請求范圍。 在內存方面,您應該考慮一下,但是隨着功能的丟失,您可能會過度優化。

簡而言之,修復方法是->

@ViewScoped
public class MyBean
{
  private List<T> myList;
  public List<T> getMyList()
  {
    if(myList != null)
      return myList;
    myList = Service.getMyList();
    return myList;
  }
}

因為您現在可以對列表進行排序並維護引用,所以該組件將起作用。 如果您確實遇到內存問題,則可以開始進行優化,即在服務端執行排序,創建一個新列表,該列表根據調用進行排序,並在請求范圍內返回。 Primefaces允許您執行此操作,但首先嘗試使用簡單方法。

// -----------回應挑剔(因為我今天有時間,這很有趣...)-------- /

我不是想和你敵對。 如果您的規模如此之大,為什么不根據您的內存負載實現一個自定義組件來處理它呢? 顯然,實體與數據庫本身之間存在一個抽象,因此可以實現自定義排序,因此您的getData()方法將能夠返回正確的排序集,而不是所維護的引用。 顯然,Primefaces(和大多數JSF實現)維護引用(有狀態),因此您需要一個低內存的解決方案。

它可能看起來像->

@RequestScoped
public class LessMemoryBean
{
  public List<T> getList()
  {
    StatefulBean state = getStatefulBean();
    //Some switch/case or other method of determining state
    return service.getSortedList(state.getState()); //I like hashmaps, but anything could work.
  }
}

@ViewScoped
public class StatefulBean
{
  private HashMap<String, Boolean> state;
  public void sortField(String key, boolean sortBy)
  {
    state.put(key, sortBy); //Construct the proper query via the keys provided
  }
}

//XHTML
<p:dataTable value="#{lessMemoryBean.data}">
  <!-- Whatever you need -->
  <p:column>
    <f:facet name="header">
      <p:commandButton 
        //Do whatever control method you want for sorting and setting booleans
      />
    </f:facet>
  </p:column>
....

因為您使用的是對RequestScoped bean的引用,並且該bean引用ViewScoped,所以您的列表存儲在請求中(由ASAP處理),但是表的狀態是分開的。 顯然,這不是開箱即用的,Primefaces支持某些偵聽器,但是您需要更深入地了解(RTFM)才能看到您的選擇。 而且,它是開源的,因此您可以簡單地擴展表以將偵聽器用作選項,而不是指向Collection的簡單鏈接。

我說的是優化,這意味着您需要做很多額外的工作。 有了它(我個人會使用標准數據表,或者在這種情況下僅實現自己的復合組件。最多1-2天不會有太多工作)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM