2012-03-19 37 views
0

我正在使用jstl進行小型測試。而且這還不是工作它是如何工作的有條件地呈現<h:commandButton>使用<c:if>

這裏是小碼:

<c:set var="id" value="#{mBlog.blog.id}"/> 
        ${id} //printing 4 
        <c:if test="${id > 0}"> 
         <h:commandButton value="Update" action="#{mBlog.update}"/> //is not rendered 
        </c:if> 

        <c:if test="${id == 0}"> 
         <h:commandButton value="Save" action="#{mBlog.save}"/> //is not rendered 
        </c:if> 

我不知道什麼是錯。在顯示屏中我只看到4個,沒有其他的。

+1

只是爲了排除顯而易見的問題,你是否爲'h'導入了正確的taglib庫?我沒有看到你的'c:if'條件有什麼明顯的錯誤;您可以通過在其中添加其他非taglib內容來輕鬆檢查執行是否會輸入這些條件。 – 2012-03-19 23:46:37

+1

看來問題與jstl無關。它與jsf有關。當在渲染頁面之前或渲染之後調用load方法時,我有一個簡短的問題:在一個頁面中,我有這個監聽器,之後我寫的代碼行在上面。它在調用load方法之前呈現jstl標籤。這是對的嗎? – Elbek 2012-03-19 23:49:57

回答

4

JSTL標記和JSF UI組件不會像編碼期望的那樣同步運行。長話短說:JSTL in JSF2 Facelets... makes sense?仔細閱讀。

在您的具體情況下,JSTL <c:if>標記條件似乎取決於JSF <f:event>標記的結果。在運行<c:if>時,在視圖編譯期間,<f:event>尚未運行,因爲它在預渲染視圖事件期間運行。因此#{mBlog.blog.id}總是null或任何其他默認值。

您需要改用JSF組件的rendered屬性。它還可以讓您的代碼更清潔。

<h:commandButton value="Update" action="#{mBlog.update}" rendered="#{mBlog.blog.id gt 0}" /> 
<h:commandButton value="Save" action="#{mBlog.save}" rendered="#{mBlog.blog.id eq 0}" /> 

然而,當調用動作時,您會遇到另一個潛在的未來問題。確保bean放入視圖範圍內,而不是在請求範圍內。

+0

感謝您的回答。我來之前做過。當我這樣做時,jsf按鈕不會調用方法(即bean中的update()方法)。我把它們分成兩種形式。不好的方式堅果我可以生存。 – Elbek 2012-03-20 19:30:59

+0

所以你的bean不在視圖範圍內。另請參閱我答案中的最後一句。這種症狀對請求範圍的bean來說是典型的,其中該按鈕是基於某個基於請求的條件呈現的,該請求條件在後續請求的應用請求值階段期間未被正確評估。如果讓bean view作用域實際上不是一個選項,你需要將'f:event'正在做的事情移到'@ PostConstruct'方法中,並使用'@ ManagedProperty'而不是''。 – BalusC 2012-03-20 19:31:24

+0

順便說一句,我發現了問題。問題出在prerenderview偵聽器到這個頁面。但jsf在渲染所有jstl標籤後調用這個方法。即在jstl mBlog.blog.id中爲null。我在prerenderview監聽器中設置了博客attr,但是在此頁面中重新傳遞jstl標籤後,此監聽器會被調用。我不知道,但似乎不應該那樣。 JSF應該先調用第一個監聽器綁定到那個頁面然後再渲染。但它是按照相反的順序進行的。 – Elbek 2012-03-20 19:33:41