不更新目标组件,但效果良好[复制]

时间:2021-12-24 20:04:51

This question already has an answer here:

这个问题已经有了答案:

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.

要让Ajax正确工作,我遇到了一个问题。在这里的xhtml文件中,我使用Ajax呈现某些输入被启用或禁用,并且它工作正常。但是,我还使用Ajax来呈现一个包含其他控件的xhtml文件,并使用id="photoEnabled"标记。当复选框未被选中时,由id="photoDisabled"标记的虚拟显示将显示在它的位置上,只需要在页面上做一个整洁的表示,并且是禁用的。

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.

相关的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>  

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.

在我的Java类中,我有各种各样的getter和setter,它们都正确地工作,包括与复选框相关的那些,以及伪Ajax方法,它只需要做一些事情。

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.

我对清单前面的一些复选框也有类似的问题,为了让它们发挥作用,我必须使用“@form”而不是特定的id,因此当单击复选框时,输入字段再次被清除。

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?

是否有人能帮助我处理我不理解的奇怪情况,是否应该在我的bean中的updateCheck()方法中放置一些代码?

Many thanks and I look forward to an interesting reply.

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

2 个解决方案

#1


11  

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

我将假设listener中的#和{之间的空格=“# {option1”。updateCheck}"只是在表述问题时出现的一个错误。这个无效的EL语法确实“不起作用”。


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:

您的具体问题归结为不了解基本的HTML/JavaScript是如何工作的(请记住,在这个问题的上下文中,JSF基本上只是一个HTML/JS代码生成器)。目前提供的代码中有两个技术问题:

  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.

    您正在尝试ajax-update一个组件,该组件本身在JSF中有条件地呈现。这样做的原因很简单:JavaScript无法通过document.getElementById()找到非呈现的JSF组件的HTML表示,以便用从ajax响应中获得的新HTML表示替换它。

    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.

    但是, 不会生成任何HTML标记(您可以通过查看jsf生成的HTML输出来确认这一点),因此JavaScript将无法找到它的HTML表示来更新它的子元素。您需要用一个JSF组件来替换它,该组件呈现一个具体的HTML元素,它可以通过通常的document.getElementById()方式进行选择,比如 ,它呈现一个HTML 元素。 片段>

    All with all, this should do:

    总之,这应该是:

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

See also:

#2


0  

If you want render particular element by id then you can use <h:form id="formId"> component globally. See below example to understand more.

如果您希望通过id呈现特定的元素,那么您可以全局地使用

组件。请看下面的例子来了解更多。

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

In the above example explaining that while selecting value h:selectBooleanCheckbox the h:inputText elements photoEnabled and photoEnabled will be refreshed.

在上面的示例中,说明在选择值h:selectBooleanCheckbox时,将刷新启用photoEnabled和启用photoEnabled的h:inputText元素。

#1


11  

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

我将假设listener中的#和{之间的空格=“# {option1”。updateCheck}"只是在表述问题时出现的一个错误。这个无效的EL语法确实“不起作用”。


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:

您的具体问题归结为不了解基本的HTML/JavaScript是如何工作的(请记住,在这个问题的上下文中,JSF基本上只是一个HTML/JS代码生成器)。目前提供的代码中有两个技术问题:

  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.

    您正在尝试ajax-update一个组件,该组件本身在JSF中有条件地呈现。这样做的原因很简单:JavaScript无法通过document.getElementById()找到非呈现的JSF组件的HTML表示,以便用从ajax响应中获得的新HTML表示替换它。

    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.

    但是, 不会生成任何HTML标记(您可以通过查看jsf生成的HTML输出来确认这一点),因此JavaScript将无法找到它的HTML表示来更新它的子元素。您需要用一个JSF组件来替换它,该组件呈现一个具体的HTML元素,它可以通过通常的document.getElementById()方式进行选择,比如 ,它呈现一个HTML 元素。 片段>

    All with all, this should do:

    总之,这应该是:

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

See also:

#2


0  

If you want render particular element by id then you can use <h:form id="formId"> component globally. See below example to understand more.

如果您希望通过id呈现特定的元素,那么您可以全局地使用

组件。请看下面的例子来了解更多。

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

In the above example explaining that while selecting value h:selectBooleanCheckbox the h:inputText elements photoEnabled and photoEnabled will be refreshed.

在上面的示例中,说明在选择值h:selectBooleanCheckbox时,将刷新启用photoEnabled和启用photoEnabled的h:inputText元素。