JSF命令按钮,带immediate=";“真的”;

JSF命令按钮,带immediate=";“真的”;,jsf,Jsf,我遇到过这样一种情况:有一个selectOneMenu,它的值绑定到一个支持bean 我需要一个不更新模型值的按钮(这就是为什么它有immediate=“true”属性) 该按钮的操作方法会更改selectOneMenu绑定到的值,但当页面重新显示时,会显示原始值(提交的值),而不是操作方法中设置的值 你知道为什么会这样吗 如果我对这个问题解释得不够好,请告诉我 编辑: 根据要求,以下是相关的源代码: 页面代码: 解决方案在划线标记的解决方案中:)因为在发布此问题后的几分钟内经常发生这种情况

我遇到过这样一种情况:有一个selectOneMenu,它的值绑定到一个支持bean

我需要一个不更新模型值的按钮(这就是为什么它有immediate=“true”属性)

该按钮的操作方法会更改selectOneMenu绑定到的值,但当页面重新显示时,会显示原始值(提交的值),而不是操作方法中设置的值

你知道为什么会这样吗

如果我对这个问题解释得不够好,请告诉我


编辑: 根据要求,以下是相关的源代码:

页面代码:
解决方案在划线标记的解决方案中:)

因为在发布此问题后的几分钟内经常发生这种情况,我找到了答案:

此处详细说明了问题的原因:

问题在于(如前所述),模型值尚未更新,因此提交的输入仍在component.submittedValue字段中,如果该字段不为空,则会显示该字段。模型更新后,它会正常清空

第一个解决方案在我的案例中不起作用,因为视图中还有其他重要的状态不能丢失。但第二个解决方案非常有效:

component.setSubmittedValue(null);

这就是所需要的:这是一个小小的额外工作,因为组件必须绑定到某个bean,但不是那么糟糕。

接下来,我认为您不需要将组件绑定到bean。如果您知道组件的客户端ID,则可以通过
UIViewRoot
FacesContext
实例中获取组件

它会有点像这样:

Foo component = (Foo)FacesContext.getCurrentInstance().getViewRoot().getComponent(clientId);

其中,
Foo
是您正在使用的组件的类,
clientId
是JSF使用的“formId:elementId”格式的组件的客户端ID。

对于我来说,这已经起到了作用:

@ManagedBean(name = "bean")
@ViewScoped
public class Bean {
    private SelectOneMenu component;

    public SelectOneMenu getComponent() {
        return selectComponent;
    }

    public void setComponent(SelectOneMenu component) {
        this.Component = component;
    }
    public void resetComponent() {
        component.resetValue();
    }
    ...
}
<h:selectOneRadio value="#{bean.value}" id = "idRadio" required="true" requiredMessage = "Required Message" binding="#{bean.component}" >
    <f:selectItem itemLabel="Value 1" itemValue="value1"/>
    <f:selectItem itemLabel="Value 2" itemValue="value2" />     
</h:selectOneRadio>

<primefaces:commandButton action="#{bean.resetComponent}" value="Erase" update="idRadio" immediate="true"/>
...
@ManagedBean(name=“bean”)
@视域
公共类Bean{
私有选择菜单组件;
public SelectOne功能表getComponent(){
返回selectComponent;
}
public void setComponent(选择一个菜单组件){
这个。组件=组件;
}
公共组件(){
component.resetValue();
}
...
}
...

谢谢。

你能发布你的JSF和bean代码吗?谢谢你的评论。这是可行的,但根据我的经验,了解clientId并不是那么容易,也不是很安全。例如,如果移动组件,嵌套它,更改组件id,更改表单id,clientid将更改,代码将停止工作。是的,同意。这对于具有ID的组件最为有效,您可以通过标记为自己分配ID,并且这些ID不是深度嵌套结构的一部分。
Foo component = (Foo)FacesContext.getCurrentInstance().getViewRoot().getComponent(clientId);
@ManagedBean(name = "bean")
@ViewScoped
public class Bean {
    private SelectOneMenu component;

    public SelectOneMenu getComponent() {
        return selectComponent;
    }

    public void setComponent(SelectOneMenu component) {
        this.Component = component;
    }
    public void resetComponent() {
        component.resetValue();
    }
    ...
}
<h:selectOneRadio value="#{bean.value}" id = "idRadio" required="true" requiredMessage = "Required Message" binding="#{bean.component}" >
    <f:selectItem itemLabel="Value 1" itemValue="value1"/>
    <f:selectItem itemLabel="Value 2" itemValue="value2" />     
</h:selectOneRadio>

<primefaces:commandButton action="#{bean.resetComponent}" value="Erase" update="idRadio" immediate="true"/>
...