我有一个问题,让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代码生成器)。目前提供的代码中有两个技术问题:
-
你正在尝试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}">
-
然而,
<ui:fragment>
不生成任何HTML标记(您可以通过查看jsf生成的HTML输出来确认这一点),因此JavaScript永远无法找到它的HTML表示来更新它的子节点。您需要用JSF组件替换它,该组件呈现一个具体的HTML元素,该元素可以通过通常的document.getElementById()
方式进行选择,就像<h:panelGroup>
呈现HTML<span>
元素一样。All with All,这应该做到:
<h:panelGroup id="photoDisabled"> <h:panelGrid columns="3" rendered="#{!option1.photometry}">
参见:
- 为什么我需要在组件中嵌套render ="#{some}"在另一个组件,当我想ajax更新它?
如果你想通过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将被刷新。