2012-12-20 92 views
0

我開始在我的項目中使用primefaces,並且馬上就出現問題。我有一些東西,我從數據庫中獲取與實體管理器的列表,並將其呈現在primefaces數據表的視圖中。我支持bean中我有:列表的GetList(),其中i檢索與實體管理器數據庫中的記錄,並返回它的時候了..Primefaces數據表排序列表

,併爲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註釋的方法中創建第一個請求時,我的列表被提取。之後,我需要保持它是最新的..
我需要知道是否有任何其他方式直接從列表中獲取列表數據庫並將其賦予primefaces而不是保留在bean中?到目前爲止,我對primefaces提供的服務並不滿意。設計非常好,但功能上存在很多錯誤。我和其他組件有類似的問題,我發現骯髒的修復,但它困擾我複雜簡單。

+3

@Bhavik:什麼**窮**編輯。這篇文章有許多問題需要改進。 – BalusC

回答

0

編輯不談,

這裏的問題是,你的名單正在從實體在每次排序時間刷新。由於每次在排序後刷新UI的方式都會設置框架,所以您需要拔出一個新列表。

基本上你所看到的 - >(這是不準確的其它是做什麼的草圖)

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

望着這意味着你有兩個不同的引用,引用排序#1,然後丟棄它並獲得一個新的渲染引用。因此你的排序不起作用。

解決方法是使用可在排序後引用的成員。這不是一個大問題,因爲您可以使用View Scope而不是Session或Request範圍。記憶方面,你是正確的想法,但你可能過度優化,因爲你失去了功能。

總之修復是 - >

@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 bean的引用和豆引用ViewScoped您的列表存儲在該請求(處置ASAP)>

@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> 
.... 

但表格的狀態是分開的。很明顯,這並非開箱即用,Primefaces支持一些聽衆,但您需要深入挖掘(RTFM)以查看您的選擇。此外,它是開源的,所以你可以簡單地擴展表來使用監聽器作爲選項,而不是簡單鏈接到Collection

你說的優化在我看來意味着你需要做很多額外的工作。有(我個人使用標準的數據表,或者只是在這種情況下實現我自己的複合組件,最多1-2天的工作量不會太大)。

+0

謝謝你的努力來解釋我所有這一切。再次,我有一個問題..爲什麼素不能只是採取列表引用,排序並使用相同的傳遞給繪圖方法..我有點困惑,總理試圖從列表中再次獲取列表這個bean並且按照排序來繪製它。我從我的方法返回的引用是匿名存儲在內存中的,並且prime可以爲它的動作引用同一個引用。 – stefo0O0o

+0

我實際上說的是: UI:列表 theList = bean.getList(); UI:sort(theList); UI:draw(theList); 我覺得這是簡單可行的算法。這將允許我使用請求範圍的bean並使排序工作。據我現在的理解,prime要求我爲他的行爲保留一個列表引用,並且他嚴格依靠我的方法來獲取相同的列表。這我不喜歡,我不知道它的工作原理是什麼,但我不喜歡它=) – stefo0O0o

+0

喜歡與否,這是實施。它必須在某處存儲對列表的引用,這意味着它由您的bean管理或由您的框架管理。這對我來說似乎是正確的實現。這很簡單,它很容易管理範圍,它允許最少的代碼來實現一些非常強大的功能。這樣看待:如果你的請求數據超出了請求的範圍,它不是請求範圍,是嗎? –