我正在尝试使用p:ajax标签,然后在该监听器中,我设置了一个名为“periodRendered”的值。然后我试图通过p:ajax标签的更新来更新h:outputLabel标签。它没有更新ajaxily,我在想它是因为一个primefaces ajax标签无法更新标准的jsf outputLabel标签。
我的假设是否正确,是否有更合适的标签我应该使用而不是h:outputLabel?
<h:outputLabel for="addProgramTo" value="Add Program To" />
<p:selectOneMenu value="#{ppBacker.grantProgram.grant_project_id}" id="addProgramTo" size="1" styleClass="listBoxMedium">
<p:ajax process=":addProgram:addProgramTo" update=":addProgram:periodGrid, :addProgram:periodLabel" event="change" listener="#{ppBacker.addProgramListener}" />
<f:selectItems value="#{ppBacker.grantProjectDropDownList}" />
</p:selectOneMenu>
<h:outputLabel for="period" value="Period" id="periodLabel" rendered="#{ppBacker.periodRendered}">
答案 0 :(得分:10)
您无法更新未呈现的元素,rendered=false
“是JSF方式”从DOM树中删除元素,
它不像css display:none
或visibility:hidden
&lt; - 这两个将保留DOM树中的元素但隐藏,而JSF rendered=false
甚至不会渲染(保留)元素在DOM树中(你甚至不会在页面的“查看源”中看到它)
所以在你的情况下你需要用{panelGroup'包装outputLabel
并更新包装器的id
<h:panelGroup id="periodLabelWrapper">
<h:outputLabel for="period" value="Period" id="periodLabel" rendered="#{ppBacker.periodRendered}">
</h:panelGroup>
并引用<p:ajax
update
属性中的包装器(始终位于DOM树中)id,如下所示:
<p:ajax process=":addProgram:addProgramTo" update=":addProgram:periodGrid, :addProgram:periodLabelWrapper" event="change" listener="#{ppBacker.addProgramListener}" />
另一种解决方案是更新整个表单,如<p:ajax update="@form" ...
,这样你就不需要包裹outputLabel
关于您的评论问题
@form如何更新未渲染的元素,但是直接通过id瞄准它们呢?
您无法定位页面中不存在的update
中的元素(呈现= false)“它不存在”
但是当您使用update="@form"
或update="someWrapperID"
时,表单/包装“重新评估”其所有内部元素,包括具有rendered="#{someBean.someCondition}"
的元素,并且条件得到“重新评估”,所以如果结果true
将显示elemet ......
答案 1 :(得分:1)
我不确定这种行为的原因,但我正在投入p:ajax将要求更新生效的活动目标。这是一个工作/不工作的例子:
<h:body styleClass="center">
<f:view contentType="text/html">
<h:form id="test">
<h:outputLabel for="addProgramTo" value="Add Program To: " />
<h:selectOneMenu id="addProgramTo" value="#{testScope.target}">
<p:ajax update=":test:periodLabel, :test:wrapper" event="change" process="@form">
</p:ajax>
<f:selectItems value="#{testScope.values}"/>
</h:selectOneMenu>
<hr />
<p:outputPanel id="wrapper">
<h:outputLabel value="Works, has a target" rendered="#{testScope.timeToRender}"/>
</p:outputPanel>
<hr />
<h:outputLabel value="does not work" id="periodLabel" rendered="#{testScope.timeToRender}" />
</h:form>
</f:view>
</h:body>
//豆...
@ViewScoped
@ManagedBean(name = "testScope")
public class TestScope
{
private String[] values = { "False", "What?", "True" };
private String target = "Nothing";
/**
* @return the target
*/
public String getTarget()
{
return target;
}
/**
* @return the values
*/
public String[] getValues()
{
System.out.println(values);
return values;
}
public boolean isTimeToRender()
{
return "True".equals(target);
}
/**
* @param target the target to set
*/
public void setTarget(String target)
{
this.target = target;
}
}
我没有时间深入研究这个,但是从调试器中快速查看(再次QUICK)看起来它没有找到ID(它没有渲染)所以它没有得到更新。为什么?我不确定 - 简单的解决方法是将它置于可以更新的内容(p:outputPanel)并将其呈现为跨度,然后您的代码应该可以工作。这可以接受吗?不是......
如果您可以处理完整表单更新,则以下内容也可以使用 - &gt;
<p:ajax update=":test" event="change" process="@form">
由于您要定位封闭表单,因此会更新所有子级。如果我这样做,那就是我使用的解决方法。这不是很多数据,而是更加清洁。我不确定这是一个错误还是一个功能。但是它感觉很麻烦。
简短回答:是的,您可以定位标签。答案很长:你不能瞄准一个没有渲染的人。我真的希望这会有所帮助。