編輯不談,
這裏的問題是,你的名單正在從實體在每次排序時間刷新。由於每次在排序後刷新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天的工作量不會太大)。
@Bhavik:什麼**窮**編輯。這篇文章有許多問題需要改進。 – BalusC