2015-09-22 92 views
2

我試圖從現有的Primefaces組件構建自定義組件,我需要一些幫助。我有一個selectOneMenu,我希望它根據在菜單中選擇哪個選項來呈現或不呈現(以及禁用或啓用)其他組件。這裏的困難之處在於我無法使用託管Bean(我有幾個原因),我需要一個純粹的xhtml代碼。有條件呈現取決於p:selectOneMenu值

我嘗試了一些<c:choose><ui:parameter>東西來創建布爾值,但由於某種原因,我看不到它不工作。你們可以看看我的代碼,看看你有什麼想法嗎?這可能是一件簡單的事,我無法想象或者我還不知道的事情。

<h:body> 
<h:form id="abc"> 
    <ui:repeat var="pd" value="#{produtoMB.produtos}"> 
     <h:panelGroup id="linha"> 
     <c:choose> 
      <c:when test="#{pd.marca == X1}"> 
       <c:set var="render" value="#{true}" /> 
      </c:when> 
      <c:otherwise> 
       <c:set var="render" value="#{false}" /> 
      </c:otherwise> 
     </c:choose> 

     <p:selectOneMenu value="#{pd.marca}"> 
      <f:selectItem itemLabel="Select One" itemValue="" noSelectionOption="true"/> 
      <f:selectItem itemLabel="Xbox One" itemValue="X1" /> 
      <f:selectItem itemLabel="PlayStation 4" itemValue="PS4" /> 
      <f:selectItem itemLabel="Wii U" itemValue="WU" /> 
      <p:ajax update="linha" /> 
     </p:selectOneMenu> 
     <p:inputText value="#{pd.aparelho}" disabled="#{render}"/> 
     <h:outputText value="Microsoft" rendered="#{render}"/> 
     <p:commandButton value="X" /> 
     </h:panelGroup> 
     <br /> 
    </ui:repeat> 
    <br /> 
    <p:commandButton actionListener="#{produtoMB.botaoMais}" value="+" update="abc"/> 
    <p:commandButton actionListener="#{produtoMB.botaoMenos}" value="-" update="abc"/> 
</h:form> 

回答

0

有幾個問題在這裏。

首先,在視圖生成時運行

<ui:repeat ...> 
    <c:choose> 
     ... 
    </c:choose> 
</ui:repeat> 

JSTL標籤。在所有JSF組件運行之前它只執行一次。因此,與您直觀地從XML代碼流中期望得到的內容相反,當<ui:repeat>組件運行並迭代時,它不會執行。又見JSTL in JSF2 Facelets... makes sense?

其次,

<c:when test="#{pd.marca == X1}"> 
... 
<f:selectItem ... itemValue="X1" /> 

itemValue="X1"表示String。 EL表達式#{X1}基本上分別在facelet,request,view,session和application作用域中查找名爲X1的變量,直到找到第一個非空值。爲了在EL中表示String值,您需要用單引號引用它,例如#{'X1'}。所以,你應該使用#{pd.marca == 'X1'}來代替。儘管如此,這還是不能解決第一點提到的原因。另見Specify conditional rendering of element inside <ui:repeat>? The <c:if> does not seem to work

但是,只要您未設置其scope屬性,就可以使用<c:set>在EL範圍中創建別名。另見Defining and reusing an EL variable in JSF page

除去JSTL <c:choose>和固定EL表達式#{X1}代表一個真實的String文字#{'X1'}結束後,這裏就應該什麼樣子:

<ui:repeat var="pd" value="#{produtoMB.produtos}"> 
    <p:selectOneMenu value="#{pd.marca}"> 
     <f:selectItem itemLabel="Select One" itemValue="#{null}" /> 
     <f:selectItem itemLabel="Xbox One" itemValue="X1" /> 
     <f:selectItem itemLabel="PlayStation 4" itemValue="PS4" /> 
     <f:selectItem itemLabel="Wii U" itemValue="WU" /> 
     <p:ajax update="linha" /> 
    </p:selectOneMenu> 
    <h:panelGroup id="linha"> 
     <c:set var="marcaIsX1" value="#{pd.marca eq 'X1'}" /> 
     <p:inputText value="#{pd.aparelho}" disabled="#{marcaIsX1}" /> 
     <h:outputText value="Microsoft" rendered="#{marcaIsX1}" /> 
    </h:panelGroup> 
    <p:commandButton value="X" /> 
</ui:repeat> 

請注意,我也刪除未使用的noSelectionOption="true"和移動<h:panelGroup id="linha">只有確實需要更新的組件。

+0

Balus,非常感謝你的回答。這確實是一個更有意義的解決方案(出於某種原因,我甚至沒有考慮過在每個「禁用」和「渲染」屬性中寫入條件的想法。在得到您的答案之前,我注意到了EL表達式中的錯誤,但也要感謝你!我真的很喜歡按照我的想法工作,但我們今生不可能擁有我們想要的,對吧?;-)非常感謝你,你救了我一天! –

+0

不客氣。 – BalusC

+0

Baulus,你認爲可能有辦法創建布爾變量並按照我第一次使用它們的方式使用它們,也許使用不同於JSTL標籤的東西?只是一個好奇心:我現在解決了我的問題,但我想到了不同的場景,我需要回到我原來的想法...... –