2013-01-24 44 views
3

我有一個簡單公司Databean這樣的:primefaces DATATABLE /排序/錯誤的項目

@Model 
Class DataBean{ 
    private List<Elements> elements; 

    @PostConstruct 
    private void loadElements(){ 
     //fetch data from database. 
    } 
} 

IM使用Primefaces數據表中顯示的數據,如下所示:

<h:form> 
<p:dataTable 
     value="#{dataBean.elements}" 
     var="element" > 

     <p:column sortBy="#{element.id}" 
      sortFunction="#{sortingHelper.sortNumericCallback}"> 
      <f:facet name="header">ID</f:facet> 
      <p:commandLink action="#{pageController.navigateToDetailView(element)}" 
       value="#{element.id}"> 
      </p:commandLink> 
     </p:column> 
</p:datatable> 
</h:form> 

pageController.navigateToDetailView(element)簡單將所選擇的元素在下一頁的databean上,所以detailView準備好了它的數據,然後返回detail-Navigation-Outcome。

現在:問題:如果我點擊其中一個commandLink而沒有任何排序,一切都很好。如果我排序編號,並單擊詳細信息鏈接,以下是發生:

  • 開始
  • 公司Databeans請求加載(postconstruct)(分選走)

現在 - 在第二次請求 - 頁面重新重建(爲了激發navigateToDetailView-Action)並且數據表「知道」,我點擊了第5行。但是沒有重新排序,第5行現在是一個不同的條目,因爲bean被重構。

不同點的控制檯輸出。

首先我點擊顯示Datatable的頁面。 「。」是我自定義排序函數的一個比較,僅僅表示集合 已排序。

13:47:56,046 INFO [stdout] (http--0.0.0.0-8090-1) -- Started Request -- 
13:47:56,047 INFO [stdout] (http--0.0.0.0-8090-1) ---- Started RESTORE_VIEW 1 ---- 
13:47:56,048 INFO [stdout] (http--0.0.0.0-8090-1) ---- Started RENDER_RESPONSE 6 ---- 
13:47:56,087 INFO [stdout] (http--0.0.0.0-8090-1) PostConstruct DataBean 
13:47:56,566 INFO [stdout] (http--0.0.0.0-8090-1) -- Finished Request -- 

這很好。現在即時通過點擊ID標頭排序

13:48:15,008 INFO [stdout] (http--0.0.0.0-8090-2) -- Started Request -- 
13:48:15,009 INFO [stdout] (http--0.0.0.0-8090-2) ---- Started RESTORE_VIEW 1 ---- 
13:48:15,051 INFO [stdout] (http--0.0.0.0-8090-2) ---- Started APPLY_REQUEST_VALUES 2 ---- 
13:48:15,052 INFO [stdout] (http--0.0.0.0-8090-2) PostConstruct DataBean 
13:48:15,124 INFO [stdout] (http--0.0.0.0-8090-2) .............................................................. 
13:48:15,124 INFO [stdout] (http--0.0.0.0-8090-2) ---- Started PROCESS_VALIDATIONS 3 ---- 
13:48:15,126 INFO [stdout] (http--0.0.0.0-8090-2) ---- Started UPDATE_MODEL_VALUES 4 ---- 
13:48:15,127 INFO [stdout] (http--0.0.0.0-8090-2) ---- Started INVOKE_APPLICATION 5 ---- 
13:48:15,127 INFO [stdout] (http--0.0.0.0-8090-2) ---- Started RENDER_RESPONSE 6 ---- 
13:48:15,387 INFO [stdout] (http--0.0.0.0-8090-2) -- Finished Request -- 

也沒關係。該表現在按照它應該被分類。現在我點擊第10行的 挑選ID爲53的項目;

13:48:28,295 INFO [stdout] (http--0.0.0.0-8090-4) -- Started Request -- 
13:48:28,296 INFO [stdout] (http--0.0.0.0-8090-4) ---- Started RESTORE_VIEW 1 ---- 
13:48:28,361 INFO [stdout] (http--0.0.0.0-8090-4) ---- Started APPLY_REQUEST_VALUES 2 ---- 
13:48:28,363 INFO [stdout] (http--0.0.0.0-8090-4) PostConstruct DataBean 
13:48:28,487 INFO [stdout] (http--0.0.0.0-8090-4) ---- Started PROCESS_VALIDATIONS 3 ---- 
13:48:28,501 INFO [stdout] (http--0.0.0.0-8090-4) ---- Started UPDATE_MODEL_VALUES 4 ---- 
13:48:28,514 INFO [stdout] (http--0.0.0.0-8090-4) ---- Started INVOKE_APPLICATION 5 ---- 
13:48:28,514 INFO [stdout] (http--0.0.0.0-8090-4) navigateToDetail() called 
13:48:28,516 INFO [stdout] (http--0.0.0.0-8090-4) Constructing ElementEditDataBean 
13:48:28,517 INFO [stdout] (http--0.0.0.0-8090-4) Setting ActiveElement to 42 
13:48:28,518 INFO [stdout] (http--0.0.0.0-8090-4) ---- Started RENDER_RESPONSE 6 ---- 
13:48:28,748 INFO [stdout] (http--0.0.0.0-8090-4) -- Finished Request -- 

請注意,在PostConstruct DataBean之後,不進行排序。 (我假設,因爲我在表中使用表格 ,數據表不知道,排序可能已經改變。)

因此,傳遞了ID爲42的元素。 (元件42在未排序的情況下,第10位)

結果,navigateToDetailView(元件)現在進行燒製與預期另一個elementthan ...

問題是OFC。排序後的集合被postconstruct方法重置。 我也知道,它可以用Conversation範圍解決。

但我想知道是否沒有無狀態的方式來做到這一點? (我不想爲每個排序/ page2page導航啓動會話)

任何想法?

編輯1: SortingHelper是自己的類,只是看起來像這樣:

@Named 
public class SortingHelper { 

/** 
* Sorts two integers correctly. 
* @param o1 integer 1 
* @param o2 integer 2 
* @return negative value if o1 is less, 0 if equal, or positive value if greater 
*/ 
public int sortNumericCallback(Object o1, Object o2) { 
    System.out.print("."); 
    int i1 = Integer.parseInt((String) o1); 
    int i2 = Integer.parseInt((String) o2); 
    return (i1 == i2) ? 0 : (i1 > i2) ? 1 : -1; 
} 
} 

(Primefaces數據表上排序整數失敗,或者可以說,它按數字字典:11 < 5等)

但即使我不介意排序和使用NO自定義排序功能,結果是相同的。

+0

是'sortFunction =「#sortingHelper.sortNumericCallback}中的'sortingHelper'」'你定義的一個類?如果是,則顯示代碼 – ClydeFrog

+0

如果執行輸出''而不是''? – ClydeFrog

+0

@ClydeFrog補充說。排序是正確的。只是,它被刪除,當我點擊鏈接到元素時,由於@ PostConstruct數據加載。而在頁面的第二次渲染(調用導航功能)中,數據表假定列表已排序,而不再。所以它'知道'我想要從第5個位置檢索元素 - 但是這個元素已經改變了。 – dognose

回答

0

從評論開始,我現在修改了Databean以便在加載後開始對話。

@ConversationScoped 
Class DataBean{ 
    private List<Elements> elements; 

    @Inject 
    private Conversation conversation; 

    @PostConstruct 
    private void loadElements(){ 
     if (this.conversation.isTransient()) 
      this.conversation.begin(); 

     //fetch data from database. 
    } 
} 
在我的PageController的導航功能

我再次停止談話:

public String navigateToDetailView(Element element) { 
    //pass element to next databean. 
    conversation.end(); 
    //... 
    return "detailView"; 
} 

然而,這導致了該問題,這回導航與瀏覽器導致無效的對話(他們結束)。

爲了解決這個問題,我創建了一個基本上禁用瀏覽器緩存的自定義過濾器,因此他們刷新頁面history.back(),因此有一個全新的,有效的對話ID。

過濾器看起來是這樣的:

public class NoCacheFilter implements Filter { 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 
     HttpServletResponse hsr = (HttpServletResponse) res; 
     hsr.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1. 
     hsr.setHeader("Pragma", "no-cache"); // HTTP 1.0. 
     hsr.setDateHeader("Expires", 0); // Proxies. 
     chain.doFilter(req, res); 
    } 

    @Override 
    public void destroy() { 
     // TODO Auto-generated method stub 
    } 

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException { 
     // TODO Auto-generated method stub 
    } 
} 

與這部分在web.xml中:

<filter> 
     <filter-name>noCacheFilter</filter-name> 
     <filter-class>com.example.NoCacheFilter</filter-class> 
    </filter> 

    <filter-mapping> 
     <filter-name>noCacheFilter</filter-name> 
     <url-pattern>*.xhtml</url-pattern> 
    </filter-mapping> 

現在我只需要弄清楚,如何結束對話如果用戶選擇沒有導航遠離側面,而不是調用showDetail() - Action。