2015-09-22 50 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标签的东西?只是一个好奇心:我现在解决了我的问题,但我想到了不同的场景,我需要回到我原来的想法...... –