immediate =“ true”を使用したJSF commandButton
-
03-07-2019 - |
質問
バッキングBeanにバインドされた値を持つselectOneMenuがある状況があります。
モデル値を更新しないボタンが必要です(そのため、immediate =" true"プロパティがあります)。
そのボタンのアクションメソッドは、selectOneMenuがバインドされている値を変更しますが、ページが再表示されると、アクションメソッドで設定された値ではなく、元の値(送信された値)が表示されます。
その理由は何ですか?
問題を十分に説明しなかった場合はお知らせください。
編集: 要求されているのは、問題のソースコードです。
ページコード:
<h:selectOneMenu id="selectedPerson"
binding="#{bindings.selectPersonComponent}"
value="#{bean.selectedPerson}">
<s:selectItems var="op" value="#{bean.allPersons}"
label="#{op.osoba.ime} #{op.osoba.prezime}"
noSelectionLabel="#{messages.selectAPerson}">
</s:selectItems>
<f:converter converterId="unmanagedEntityConverter" />
</h:selectOneMenu>
...
<a4j:commandButton action="#{bean.createNew}" value="#{messages.createNew}"
immediate="true" reRender="panelImovine">
</a4j:commandButton>
javaコード:
private Person selectedPerson;
public String createNew() {
log.debug("New created...");
selectedPerson = null;
bindings.getSelectPersonComponent().setSubmittedValue(null); //SOLUTION
return "";
}
ソリューションは SOLUTION とマークされた裏地にあります:)
解決
この質問を投稿してからしばらくすると頻繁に起こるので、答えを見つけました:
問題の原因について詳しくは、 ClearInputComponents
問題は(説明したように)モデル値が更新されていないため、送信された入力がcomponent.submittedValueフィールドにあり、空でない場合はそのフィールドが表示されることです。モデルが更新されると、通常は空になります。
私の場合、最初の解決策はうまくいきませんでした。ビューには他の重要な状態が失われてはならないからです。しかし、2番目の解決策はうまくいきました。
component.setSubmittedValue(null);
それで必要なのはそれだけでした。コンポーネントを何らかのBeanにバインドする必要があるため、少し余分な作業が必要になりますが、それほど悪くはありません。
他のヒント
少しフォローアップするために、コンポーネントをBeanにバインドする必要はないと思います。コンポーネントのクライアントIDがわかっている場合は、 UIViewRoot
を介して FacesContext
インスタンスからコンポーネントを取得できます。
次のようになります:
Foo component = (Foo)FacesContext.getCurrentInstance().getViewRoot().getComponent(clientId);
Foo
は使用しているコンポーネントのクラス、 clientId
は&quot; formId:elementId&quot;内のコンポーネントのクライアントIDです。 JSFが使用する形式。
私にとって、これはうまくいきました:
@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"/>
...
ありがとう。