【问题标题】:h:commandButton f:ajax execution trigger expressions from another formh:commandButton f:ajax 执行从另一个表单触发表达式
【发布时间】:2019-06-24 01:15:01
【问题描述】:

我们有复杂的 JSF 页面,由可重复的 primefaces 组件组成,例如 p:dataTable、p:tabView、ui:repeat、c:foreach、javascript 等。 该页面由两个单独的表单组成,ID 分别为 formHeaderformBPM 奇怪的是,执行放在 formHeader 中的 h:commandButton 会导致调用 formBPM 中的所有 getter、render 和 test 表达式。在 RestoreView 和 RenderResponse 阶段都会调用表达式。

<h:form id="formHeader" enctype="multipart/form-data;charset=UTF-8">            
 <h:commandButton value="Call this"  type="button">
                        <f:ajax execute="@this"  />
 </h:commandButton>
</h:form>
<h:form id="formBpm">
 <p:tabView...>
  <p:dataTable....>
  </p:dataTable>
 ....
 </p:tabView>
</h:form>

原始页面过于复杂,被动态组件和java脚本超载。 但是我已经以简化的结构对上面的页面进行了建模并检查了日志记录

<h:form id="formHeader" enctype="multipart/form-data;charset=UTF-8">            
    <h:commandButton value="Call this"  type="button">
                <f:ajax execute="@this"  />
    </h:commandButton>
    <h:commandButton value="Call form render form"  type="button">
                <f:ajax execute="@form" render="@form"/>
    </h:commandButton>
    <h:commandButton value="Call formBpm"  type="button">
                <f:ajax execute=":formBpm"/>
    </h:commandButton>
    <h:commandButton value="Call formBpm render formBpm"  type="button">
                <f:ajax execute=":formBpm" render=":formBpm"/>
    </h:commandButton>
    <p:outputLabel id="labelThisid" value="#{testBean.varThis}"></p:outputLabel>
</h:form>
<h:form id="formBpm">
    <p:outputLabel id="labelid" value="#{testBean.var1}"></p:outputLabel>
    <p:tabView  id="tabViewId" >
        <p:tab id="tabId1" title="#{testBean.tab1}">
        </p:tab>
        <p:tab id="tabId2" title="#{testBean.tab2}" rendered="#{testBean.tab2Show}">
        </p:tab>
    </p:tabView>
</h:form>

根据日志,在 simplified 页面上,没有在单击“调用此”时执行 getter,只有在呈现适当的表单时才会执行它们,而不是执行。此外,getter 仅在 RenderResponse 阶段被调用。 原始复杂页面上调用不适当的getter的原因可能是什么?

Primefaces 6.1 jBoss EAP 6.4 JSF Mojarra 2.1.28

【问题讨论】:

  • 这可能很有趣,虽然没有说明为什么表单 A 中的交互会触发表单 B 中的内容:stackoverflow.com/questions/2090033/…
  • 添加一个 jsf 生命周期调试器并检查这发生在哪个生命周期中,Restoreview 最有可能
  • 感谢提议,jsf生命周期调试器已经有了。 Getter 在 RESTORE_VIEW 和 RENDER_RESPONSE 阶段都被调用。
  • 我期待的是 RESTORE_VIEW(并不是我的期待是正确的,只是我的知识有限,我只是期待它)。 RENDER_RESPONSE 我没想到。这些表格周围有没有偶然的表格。
  • 您可以尝试在每个 jsf 标签上创建一个带有显式 ID 的 minimal reproducible example,以便在调试时在 http 请求/响应中显示得更好吗?你的 JSF 实现和版本是什么?还有PF那个?当页面中不使用 PrimeFaces 元素或根本不使用 PF 时,它是否有效?

标签: performance jsf primefaces


【解决方案1】:

解决办法是,jstl标签中的表达式不管被点击的commandButton的执行容器如何都会被执行。在我们的原始页面中,有时将相同的表达式用作值获取器和 jstl 标记的测试表达式。因此,在下面的代码表达式中,当单击“调用此”按钮时,将执行 #{testBean.tab2Show}。此外,测试表达式在 RestoreView 和 RenderResponse 阶段被调用了两次。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html 
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:p="http://primefaces.org/ui"
    >     
    <h:head>
        <h2>Check jstl with AJAX </h2>
    </h:head>    
    <h:body>
        <h:form id="formHeader" enctype="multipart/form-data;charset=UTF-8">            
            <h:commandButton value="Call this">
                        <f:ajax execute="@this"  />
            </h:commandButton>
            <p:outputLabel id="labelThisid" value="#{testBean.varThis}"></p:outputLabel>
        </h:form>
        <h:form id="formBpm">
            <c:if test="#{testBean.tab2Show}">
                <p:outputLabel id="labelid" value="#{testBean.var1}"></p:outputLabel>
            </c:if>
            <p:tabView  id="tabViewId" >
                <p:tab id="tabId1" title="#{testBean.tab1}">
                </p:tab>
                <p:tab id="tabId2" title="#{testBean.tab2}">
                </p:tab>
            </p:tabView>
        </h:form>
    </h:body>
</html>

TestBean

public String getVar1() {
    log.debug("getVar1");
    return "getVar1";
}

public String getVarThis() {
    log.debug("getVarThis");
    return "getVarThis";
}

public String getTab1() {
    log.debug("getTab1");
    return "getTab1";
}

public String getTab2() {
    log.debug("getTab2");
    return "getTab2";
}

public boolean isTab2Show() {
    log.debug("isTab2Show");
    return true;
}

PhaseListener 登录单击按钮“调用此”

18:30:27,298 DEBUG [utils.LifeCycleListener:26] - START PHASE RESTORE_VIEW 1
18:30:27,300 DEBUG [utils.TestBean:48] - isTab2Show
18:30:27,300 DEBUG [utils.LifeCycleListener:30] - END PHASE RESTORE_VIEW 1
18:30:27,301 DEBUG [utils.LifeCycleListener:26] - START PHASE APPLY_REQUEST_VALUES 2
18:30:27,302 DEBUG [utils.LifeCycleListener:30] - END PHASE APPLY_REQUEST_VALUES 2
18:30:27,303 DEBUG [utils.LifeCycleListener:26] - START PHASE PROCESS_VALIDATIONS 3
18:30:27,303 DEBUG [utils.LifeCycleListener:30] - END PHASE PROCESS_VALIDATIONS 3
18:30:27,303 DEBUG [utils.LifeCycleListener:26] - START PHASE UPDATE_MODEL_VALUES 4
18:30:27,303 DEBUG [utils.LifeCycleListener:30] - END PHASE UPDATE_MODEL_VALUES 4
18:30:27,303 DEBUG [utils.LifeCycleListener:24] - START INVOKE_APPLICATION
18:30:27,303 DEBUG [utils.LifeCycleListener:26] - START PHASE INVOKE_APPLICATION 5
18:30:27,303 DEBUG [utils.LifeCycleListener:30] - END PHASE INVOKE_APPLICATION 5
18:30:27,303 DEBUG [utils.LifeCycleListener:26] - START PHASE RENDER_RESPONSE 6
18:30:27,303 DEBUG [utils.TestBean:48] - isTab2Show
18:30:27,304 DEBUG [utils.LifeCycleListener:30] - END PHASE RENDER_RESPONSE 6

【讨论】:

  • 当我使用 ajax 时,我没想到会出现这种情况......当然没有其他东西会导致 ajax 失败并刷新整页?
  • 我已将完整代码添加到答案中,您可以查看。
  • 谢谢,我可以试试。非常好奇 stackoverflow.com/questions/3342984/… 表示 jstl 在视图构建中“运行”,stackoverflow.com/questions/31890433/whats-the-view-build-time 表示视图构建不是一个阶段。如果您删除 commandButton 上的 `type="button" 会怎样?
  • 他们声明视图构建可以发生在不同的阶段。在我的发布请求视图构建的情况下,在恢复视图阶段和呈现响应阶段执行。删除 type="button" 不会更改日志。
  • 这是在哪里说明的?我似乎无法找到该信息。更新,我确实在其他地方找到了它……嗯……对我来说是新信息。但是问题仍然存在,为什么它并不总是发生......
猜你喜欢
  • 2013-06-08
  • 2014-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多