JSF 中的条件问题

发布于 2024-10-24 16:27:28 字数 644 浏览 2 评论 0原文

我有以下代码:

<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 returned="#{show}" 时,也会发生同样的事情

I have the code bellow:

<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>

When show=false, show only the second link.
And it works. I can reach server (I'm using debug to see this).

When show=true, both links appears. But ONLY second link works. The link inside conditional doesn't trigger the action in server.

Someone, can, please, help me?

Note: the same thing happens when I use a4j:outputPanel rendered="#{show}"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

花开雨落又逢春i 2024-10-31 16:27:28

在处理表单提交期间,JSF 将重新评估命令按钮/链接是否已呈现。如果没有渲染,那么它将简单地跳过该操作。

您需要确保当 JSF 处理表单提交时,表达式 #{cartBean.itemsAdded} 也返回 true。一个简单的测试是将 bean 放入会话范围中(我假设 isItemsAdded() 是一个纯 getter,即它仅包含 return itemsAdded; )。

如果这确实解决了问题并且您希望将 bean 保留在请求范围内,请添加 在后续请求中保留 bean 属性。

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

另请参阅:


与具体问题无关,您应该更喜欢 JSF尽可能多地使用 JSTL 的标签/属性。在这种特殊情况下,您应该删除两个 JSTL 标记并使用 JSF 提供的 rendered 属性:

<h:form id="test1" rendered="#{cartBean.itemsAdded}">
    <h:commandLink action="#{cartBean.foo}">this doesn't work</h:commandLink>           
</h:form>

During processing of the form submit, JSF will re-evaluate whether the command button/link is been rendered. If it is not rendered, then it will simply skip the action.

You need to ensure that the expression #{cartBean.itemsAdded} returns true as well when the form submit is been processed by JSF. An easy test is to put the bean in the session scope (and I assume that the isItemsAdded() is a pure getter, i.e. it contains only return itemsAdded;).

If that did fix the problem and you'd like to keep the bean in the request scope, then add a <a4j:keepAlive> to retain the bean properties in the subsequent request.

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

See also:


Unrelated to the concrete problem, you should prefer JSF tags/attributes over JSTL ones as much as possible. In this particular case, you should get rid of both JSTL <c:> tags and use the JSF-provided rendered attribute instead:

<h:form id="test1" rendered="#{cartBean.itemsAdded}">
    <h:commandLink action="#{cartBean.foo}">this doesn't work</h:commandLink>           
</h:form>
青衫儰鉨ミ守葔 2024-10-31 16:27:28

解决方案

我不想使用 sessionScope,因为在大型系统中使用它存在危险(我的情况)。我不喜欢使用 keepAlive neighter,因为我在一个混乱的服务器中,并且许多属性不可序列化。

无论如何,我找到了这个解决方法:

  1. 在请求中发送一个参数(例如 show=true)
  2. 更改检查方法,添加一个 OR 作为回报以查看这个新参数。

托管 Bean:

之前:

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>

WORKARROUND:

I don't want to use sessionScope, because of the danger of use this in a huge system (my case). I don't like to use keepAlive neighter, because I'm in a clutered server and many attributes are not serializable.

Anyway, I've found this workarround:

  1. Send a parameter in request (like show=true)
  2. Change the check method, adding a OR in return to see this new parameter.

MANAGED BEAN:

Before:

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

After:

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

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

XHTML:

Before:

<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>

After:

<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>
千里故人稀 2024-10-31 16:27:28

改进(和微小)的解决方法:

仅更改 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>

IMPROVED (and tiny) WORKARROUND:

Change only XHTML:

Before:

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

After:

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文