<f:ajax render =“someId”>不更新目标组件,但<f:ajax render =“@ form”>工作正常</f:ajax> </f:ajax>

时间:2013-04-03 12:27:33

标签: ajax jsf

我遇到了使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()方法中吗?

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

2 个答案:

答案 0 :(得分:11)

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


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

  1. 您正在尝试ajax更新一个在JSF中有条件地呈现的组件。这不会起作用,原因很简单,JavaScript无法通过document.getElementById()找到非呈现的JSF组件的HTML表示,以便将其替换为从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元素,例如呈现HTML <h:panelGroup>元素的<span>

    总而言之,这应该做到:

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

答案 1 :(得分: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。