< f:ajax render =" someId">不会更新目标组件,而是< f:ajax render ="@ form">工作正常 [英] <f:ajax render="someId"> does not update target component, but <f:ajax render="@form"> works fine

查看:49
本文介绍了< f:ajax render =" someId">不会更新目标组件,而是< f:ajax render ="@ form">工作正常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使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,它们都可以正常工作,包括与复选框相关联的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()方法中放置一些代码吗?

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

解决方案

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


您的具体问题归结为缺乏对基本HTML/JavaScript的工作方式的了解(请记住,在该问题的上下文中,JSF基本上只是HTML/JS代码生成器).到目前为止,所提供的代码中存在2个技术问题:

  1. 您正在尝试ajax更新一个组件,该组件本身是有条件地在JSF中呈现的.由于JavaScript无法通过document.getElementById()找不到未渲染的JSF组件的HTML表示形式,以将其替换为从ajax响应中获得的新HTML表示形式,因此,这将不起作用. /p>

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

    <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组件替换它,该组件呈现一个具体的HTML元素,该元素可以用通常的document.getElementById()方式选择,例如<h:panelGroup>呈现一个HTML <span>元素.

    所有,这应该做到:

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

另请参见:

I am having a problem getting Ajax to work correctly. In the xhtml file I have here I am using Ajax to render some input being enabled or disabled, and it works correctly. However, further down I am also using Ajax to render an included xhtml file which contains a amongst other controls, and is tagged with id="photoEnabled". When the checkbox is not checked, a dummy display tagged by id="photoDisabled" is show in its place simply for a tidy presentation on the page, and is disabled.

For some reason this does not work, and I do not understand why. However, if I replace:

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

it does work correctly, but the problem is that further up on the page and not shown here, I have some other input fields, and when the status of the checkbox is changed, the fields are cleared because the whole form is rendered, which I do not want.

The relevant xhtml code is here, with the two Ajax tags shown, one which works and the other which does not.

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

In my Java class I have various getters and setters, which all work correctly, include those associated with the checkboxes, and dummy Ajax method which does nothing but appears to be required.

Part of the code is here:

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) {}  

I am having a similar problem with some checkboxes earlier in the listing, and for them to work I have to use "@form" rather than specific ids, so again input fields are cleared when a checkbox is clicked.

Can someone kindly help me with the strange situation which I do not understand, and should some code be placed in the updateCheck() method in my bean?

Many thanks and I look forward to an interesting reply.

解决方案

I'll assume that the space between # and { in listener="# {option1.updateCheck}" is just a careless typo while formulating the question. This invalid EL syntax indeed "does not work".


Your concrete problem boils down to lack of understanding how basic HTML/JavaScript works (remember, JSF is in the context of this question basically just a HTML/JS code generator). There are 2 technical problems in the code provided so far:

  1. You're trying to ajax-update a component which is by itself conditionally rendered in JSF. This won't work for the simple reason that JavaScript wouldn't be able to find the HTML representation of a non-rendered JSF component by document.getElementById() in order to replace it with the new HTML representation as obtained from the ajax response.

    You need to put it in a component which is always rendered. E.g. this

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

    theoretically needs to be replaced by

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


  2. However, the <ui:fragment> doesn't generate any HTML markup (you can confirm this by just looking at JSF-generated HTML output), so JavaScript wouldn't ever be able to find its HTML representation in order to update its children. You need to replace it by a JSF component which renders a concrete HTML element which is selectable by the usual document.getElementById() way, like a <h:panelGroup> which renders a HTML <span> element.

    All with all, this should do:

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

See also:

这篇关于&lt; f:ajax render =&quot; someId&quot;&gt;不会更新目标组件,而是&lt; f:ajax render ="@ form"&gt;工作正常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆