Проблемы с условностями в JSF - PullRequest
1 голос
/ 17 марта 2011

У меня есть код ниже:

<c:set var="show" value="#{cartBean.itemsAdded}" />

<c:if test="${show}">
    <h:form id="test1">
        <h:commandLink action="#{cartBean.foo}">this doesn't work</h:commandLink>           
    </h:form>
</c:if>

<h:form id="test2">
    <h:commandLink action="#{cartBean.foo}">this works!</h:commandLink>         
</h:form>

Когда show = false, показывать только вторую ссылку.И это работает.Я могу связаться с сервером (я использую отладку, чтобы увидеть это).

Когда show = true, обе ссылки появляются.Но ТОЛЬКО вторая ссылка работает.Ссылка внутри условия не запускает действие на сервере.

Кто-то может мне помочь?

Примечание: то же самое происходит при использовании a4j: outputPanel render= "# {показать}"

Ответы [ 3 ]

2 голосов
/ 17 марта 2011

Во время обработки отправки формы JSF повторно оценит, была ли отображена командная кнопка / ссылка.Если он не отображается, он просто пропустит действие.

Необходимо убедиться, что выражение #{cartBean.itemsAdded} также возвращает true, когда отправка формы обрабатывается JSF.Простой тест состоит в том, чтобы поместить компонент в область действия сеанса (и я предполагаю, что isItemsAdded() является чистым получателем, то есть содержит только return itemsAdded;).

Если это решило проблему, и вы 'Я хотел бы сохранить компонент в области запроса, затем добавьте <a4j:keepAlive>, чтобы сохранить свойства компонента в следующем запросе.

<a4j:keepAlive beanName="#{cartBean}" />

См. также:


Независимо от конкретной проблемы, вы должны как можно больше предпочитать теги / атрибуты JSF, а не JSTL.В этом конкретном случае вы должны избавиться от обоих тегов JSTL <c:> и использовать вместо этого предоставленный JSF атрибут rendered:

<h:form id="test1" rendered="#{cartBean.itemsAdded}">
    <h:commandLink action="#{cartBean.foo}">this doesn't work</h:commandLink>           
</h:form>
1 голос
/ 15 апреля 2011

WORKARROUND

Я не хочу использовать sessionScope из-за опасности использования этого в огромной системе (мой случай). Мне не нравится использовать keepAlive сосед, потому что я на кластерном сервере, и многие атрибуты не сериализуемы.

В любом случае, я нашел этот обходной путь:

  1. Отправить параметр в запросе (например, show = true)
  2. Измените метод проверки, добавив ИЛИ взамен, чтобы увидеть этот новый параметр.

Управляемый боб:

До:

public boolean itemsAdded() {
    return foo; // my initial check
}

После того, как:

public HttpServletRequest getRequest() {
        return (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
}

public boolean itemsAdded() {
    return foo || getRequest().getParameter("show") != null;
}

XHTML:

До:

<c:set var="show" value="#{cartBean.itemsAdded}" />
<c:if test="${show}">
    <h:form id="test1">
        <h:commandLink action="#{cartBean.foo}">link</h:commandLink>           
    </h:form>
</c:if>

После того, как:

<c:set var="show" value="#{cartBean.itemsAdded}" />
<c:if test="${show}">
    <h:form id="test1">
       <h:commandLink action="#{cartBean.foo}">link
          <f:param name="show" value="true"/>
       </h:commandLink> 
    </h:form>
</c:if>
0 голосов
/ 15 апреля 2011

УЛУЧШЕНО (и крошечное) ВРЕМЕННОЕ РЕШЕНИЕ:

Изменить только XHTML:

До:

<c:if test="#{cartBean.itemsAdded}">
    <h:form id="test1">
        <h:commandLink action="#{cartBean.foo}">link</h:commandLink>           
    </h:form>
</c:if>

После:

<c:if test="#{cartBean.itemsAdded || params['show']}">
    <h:form id="test1">
       <h:commandLink action="#{cartBean.foo}">link
          <f:param name="show" value="true"/>
       </h:commandLink> 
    </h:form>
</c:if>
...