2015-09-22 10 views
2

Я пытаюсь создать пользовательский компонент из существующих компонентов Primefaces, и мне нужна помощь здесь. У меня есть selectOneMenu, и я хочу, чтобы он отображал или нет (и отключает или разрешает) другие компоненты, в зависимости от того, какой параметр выбран в меню. Трудно здесь, что я не могу сделать это, используя Managed Bean (у меня есть несколько причин для этого), мне нужен чистый xhtml-код.Условно рендеринг зависит от p: selectOneMenu value

Я пробовал кое-какие <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" /> 

The itemValue="X1" представляет собой String. Выражение EL #{X1} в основном ищет переменную с именем X1 соответственно в области зрения, запроса, представления, сеанса и приложения до тех пор, пока не будет найдено первое ненулевое значение. Чтобы представить значение String в EL, вам нужно процитировать его с помощью отдельных тактов #{'X1'}. Итак, вы должны были использовать #{pd.marca == 'X1'}. Тем не менее, это по-прежнему не будет работать по причине, упомянутой в первом пункте. См. Также Specify conditional rendering of element inside <ui:repeat>? The <c:if> does not seem to work.

Вы можете использовать <c:set> для создания псевдонима в области EL, если вы не установили его атрибут scope. См. Также 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? Просто любопытство: я решил проблему сейчас, но я думаю о разных сценариях, в которых мне нужно будет вернуться к моей оригинальной идее ... –