2

我在让 Ajax 正常工作时遇到问题。在我在这里的 xhtml 文件中,我使用 Ajax 来呈现启用或禁用的某些输入,并且它可以正常工作。但是,再往下,我还使用 Ajax 来呈现包含的 xhtml 文件,该文件包含其他控件,并带有 id="photoEnabled" 标记。如果未选中该复选框,则会在其位置显示一个由 id="photoDisabled" 标记的虚拟显示,只是为了在页面上进行整洁的演示,并且会被禁用。

由于某种原因,这不起作用,我不明白为什么。但是,如果我更换:

<h:selectBooleanCheckbox id="photometry" value="#{option1.photometry}">   
  <f:ajax event="click" render="photoEnabled photoDisabled" listener="# {option1.updateCheck}"/>   
</h:selectBooleanCheckbox>   

<!-- by -->   

<h:selectBooleanCheckbox id="photometry" value="#{option1.photometry}">   
  <f:ajax event="click" render="@form" listener="#{option1.updateCheck}"/>   
</h:selectBooleanCheckbox>  

它确实可以正常工作,但问题是在页面的更上方并且未在此处显示,我还有一些其他输入字段,并且当复选框的状态发生更改时,由于呈现了整个表单,因此这些字段被清除,我不要。

相关的 xhtml 代码在这里,显示了两个 Ajax 标记,一个有效,另一个无效。

 <p:fieldset id="chooseOutput" legend="and choose your output:" style="text-align:left">   
    <h:commandButton id="popupChooseOutput" type="button" value="?" onclick="openPopup(420,370,'popups/helpOpt12')"  
                     styleClass="queryButton"/>   
    <p:panelGrid id="specphot" styleClass="textCentered" style="margin-left:auto; margin-right:auto">   
      <p:row>   
        <p:column colspan="2">   
          <span></span>   
        </p:column>   
        <p:column>   
          <h:outputText value="λ<sub>1</sub>(Å)" escape="false"/>   
        </p:column>   
        <p:column>   
          <p:spacer width="2" height="0"/>   
        </p:column>   
        <p:column>   
          <h:outputText value="λ<sub>2</sub>(Å)" escape="false"/>   
        </p:column>   
        <p:column>   
          <p:spacer width="2" height="0"/>   
        </p:column>   
        <p:column>   
          <h:outputText value="Δλ(Å)" escape="false"/>   
        </p:column>   
        <p:column>   
          <p:spacer width="2" height="0"/>   
        </p:column>   
        <p:column>   
          <h:outputText value="R"/>   
        </p:column>   
        <p:column>   
          <p:spacer width="2" height="0"/>   
        </p:column>   
        <p:column>   
          <h:outputText value="<i>v</i>sin <i>i</i> (km/s)" escape="false"/>   
        </p:column>   
      </p:row>     
      <p:row>   
        <p:column>   
          <h:selectBooleanCheckbox id="spectrum" value="#{option1.spectrum}">   
            <f:ajax event="click" render="deltaLambda lambda1 lambda2 R vsini" listener="#{option1.updateCheck}"/><!-- This works -->   
          </h:selectBooleanCheckbox>   
        </p:column>   
        <p:column style="text-align:left">   
          <h:outputText value="Spectrum:" escape="false"/>   
        </p:column>   
        <p:column>   
          <h:inputText size="6" id="lambda1" value="#{simulator.lam1}" disabled="#{!option1.spectrum}"  
                       styleClass="#{option1.enableStyle}"/>   
        </p:column>   
        <p:column>   
          <div></div>   
        </p:column>   
        <p:column>   
          <h:inputText size="6" id="lambda2" value="#{simulator.lam2}" disabled="#{!option1.spectrum}"  
                       styleClass="#{option1.enableStyle}"/>   
        </p:column>   
        <p:column>   
          <div></div>   
        </p:column>   
        <p:column>   
          <h:inputText size="6" id="deltaLambda" value="#{simulator.dlam}" disabled="#{!option1.spectrum}"  
                       styleClass="#{option1.enableStyle}"/>   
        </p:column>   
        <p:column>   
          <div></div>   
        </p:column>   
        <p:column>   
          <h:inputText size="6" id="R" value="#{simulator.lamByDlam}" disabled="#{!option1.spectrum}"  
                       styleClass="#{option1.enableStyle}"/>   
        </p:column>   
        <p:column>   
          <div></div>   
        </p:column>   
        <p:column>   
          <h:inputText size="6" id="vsini"   value="#{option1.vsini}" disabled="#{!option1.spectrum}"  
                       styleClass="#{option1.enableStyle}"/>   
        </p:column>   
      </p:row>   
      <p:row>   
        <p:column>   
          <h:selectBooleanCheckbox id="photometry" value="#{option1.photometry}">   
            <f:ajax event="click" render="photoEnabled photoDisabled" listener="#{option1.updateCheck}"/><!-- This does not work -->   
          </h:selectBooleanCheckbox>   
        </p:column>   
        <p:column style="text-align:left">   
          <h:outputText value="Photometry:"/>   
        </p:column>   
        <p:column colspan="9">   

          <!-- Conditionally enable filter menu here and in Option 2.  ""hiddenPhoto" is used by   
               JavaScript to test if any user defined filter files have been selected if it is "1".   
               If it is, it then tests if any files have been uploaded, in which case the user is   
               then given the choice of canceling the operation or deleting the uploaded files. -->   

          <h:outputText id="hiddenPhoto" class="hide" value="#{filters.displayUserDefined}"/>   

          <ui:fragment id="photoEnabled" rendered="#{option1.photometry}">   
            <ui:include src="include/filterMenu.xhtml"/>   
          </ui:fragment>   

          <!-- When the filter menu is disabled display the disabled menu in its place with the background color -->   

          <ui:fragment id="photoDisabled" rendered="#{!option1.photometry}">   
            <h:panelGrid columns="3">   
              <h:selectOneMenu value="#{filters.filterSet}" styleClass="filterMenuDisabled" disabled="true">   
                <f:selectItems value="#{filters.filtersMap}"/>   
              </h:selectOneMenu>   
              <h:selectOneRadio value="#{filters.radioValue}" disabled="true">   
                <f:selectItem itemValue="" itemLabel="AB"/>   
                <f:selectItem itemValue="" itemLabel="Vega"/>   
              </h:selectOneRadio>   
            </h:panelGrid>   
          </ui:fragment>   

        </p:column>   
      </p:row>   
    </p:panelGrid>   
  </p:fieldset>  

在我的 Java 类中,我有各种 getter 和 setter,它们都可以正常工作,包括与复选框相关联的那些,以及似乎是必需的虚拟 Ajax 方法。

部分代码在这里:

public boolean isSpectrum() {   
  return spectrum;   
}   

public void setSpectrum(boolean spectrum) {   
  this.spectrum = spectrum;   
}   

public boolean isPhotometry() {   
  return photometry;   
}   

public void setPhotometry(boolean photometry) {   
  this.photometry = photometry;   
} 

public void updateCheck(AjaxBehaviorEvent event) {}  

我在清单前面的一些复选框中遇到了类似的问题,为了使它们起作用,我必须使用“@form”而不是特定的 ID,因此当单击复选框时,输入字段再次被清除。

有人可以帮我解决我不明白的奇怪情况吗,是否应该在我的 bean 的 updateCheck() 方法中放置一些代码?

非常感谢,我期待着一个有趣的答复。

4

2 回答 2

15

我会假设在提出问题时,#和之间{的空格listener="# {option1.updateCheck}"只是一个粗心的错字。这种无效的 EL 语法确实“不起作用”。


您的具体问题归结为缺乏对基本 HTML/JavaScript 工作原理的理解(请记住,JSF 在这个问题的上下文中基本上只是一个 HTML/JS 代码生成器)。目前提供的代码存在2个技术问题:

  1. 您正在尝试 ajax 更新一个组件,该组件本身在 JSF 中有条件地呈现。这将不起作用,原因很简单,即 JavaScript 无法找到未呈现的 JSF 组件的 HTML 表示,document.getElementById()以便将其替换为从 ajax 响应中获得的新 HTML 表示。

    您需要将它放在始终呈现的组件中。例如这个

    <ui:fragment id="photoDisabled" rendered="#{!option1.photometry}">
        <h:panelGrid columns="3">
    

    理论上需要换成

    <ui:fragment id="photoDisabled">
        <h:panelGrid columns="3" rendered="#{!option1.photometry}">
    

  2. 但是<ui:fragment>它不会生成任何 HTML 标记(您可以通过查看 JSF 生成的 HTML 输出来确认这一点),因此 JavaScript 永远无法找到它的 HTML 表示来更新其子代。您需要用一个 JSF 组件替换它,该组件呈现一个可以通过通常document.getElementById()方式选择的具体 HTML 元素,就像<h:panelGroup>呈现 HTML<span>元素的 a 一样。

    总而言之,这应该这样做:

    <h:panelGroup id="photoDisabled">
        <h:panelGrid columns="3" rendered="#{!option1.photometry}">
    

也可以看看:

于 2013-04-03T12:53:58.143 回答
0

如果你想通过 id 渲染特定元素,那么你可以<h:form id="formId">全局使用组件。请参阅下面的示例以了解更多信息。

  <h:form id="formId">
    <h:inputText id="photoEnabled" value="#{bean.photoEnaled}"/>
    <h:inputText id="photoEnabled" value="#{bean.photoDisabled}"/>
    ....
    <h:selectBooleanCheckbox id="photometry" value="#{option1.photometry}">   
       <f:ajax event="click" render=":formId:photoEnabled :formId:photoDisabled" listener="# {option1.updateCheck}"/>   
     </h:selectBooleanCheckbox>   
                ...
   </h:form>

在上面的示例中,解释了在选择值 h:selectBooleanCheckbox时,h:inputText元素 photoEnabled 和 photoEnabled 将被刷新。

于 2015-03-12T07:46:23.060 回答