3

selectOneMenu から別のスキンを選択したときに、inputTexts の値を変更したいと考えています。私のコンバーターはメニューから正しいオブジェクトを返しますが、inputTexts は更新されません。

<h:form>
    <h:selectOneMenu id="dropdownSkin"
        value="#{helloBean.currentSkin}" defaultLabel="Select a skin.."
        valueChangeListener="#{helloBean.skinValueChanged}" immediate="true"
        onchange="this.form.submit()" converter="SkinConverter" >
        <f:selectItems value="#{helloBean.mySkinsSI}" var="c"
            itemValue="#{c.value}" />
    </h:selectOneMenu>


    <br />
    <h:inputText id="name" value="#{helloBean.currentSkin.title}"></h:inputText>
    <br />
    <h:inputText id="tcolor" value="#{helloBean.currentSkin.titleBar.textColor}"></h:inputText>
    <br />
    <h:inputText id="bcolor" value="#{helloBean.currentSkin.titleBar.backgroundColorStart}"></h:inputText>
</h:form>

これが私のBeanの外観です。私はそれをデバッグし、オブジェクト currentSkin が正しく設定されています。テキストフィールドの内容を更新する方法を知る必要があります。

@ManagedBean
@SessionScoped
public class HelloBean implements Serializable {

private static final long serialVersionUID = 1L;

private List<ExtendedSkin> mySkins;
private List<SelectItem> mySkinsSI;
private ExtendedSkin currentSkin;

public void skinValueChanged(ValueChangeEvent e) {
    currentSkin = (ExtendedSkin) e.getNewValue();
    FacesContext.getCurrentInstance().renderResponse();
}

public List<ExtendedSkin> getMySkins() {
    mySkins = XMLParser.readExtendedSkins();
    return mySkins;
}

public List<SelectItem> getMySkinsSI() {
    mySkinsSI = new LinkedList<SelectItem>();
    for (ExtendedSkin s : getMySkins()) {
        mySkinsSI.add(new SelectItem(s, s.getTitle()));
    }
    return mySkinsSI;
}

public void setMySkinsSI(List<SelectItem> myItems) {
    this.mySkinsSI = myItems;
}

public ExtendedSkin getCurrentSkin() {
    if (currentSkin == null) {
        currentSkin = getMySkins().get(0);
    }
    return currentSkin;
}

public void setCurrentSkin(ExtendedSkin currentSkin) {
    this.currentSkin = currentSkin;
}
}
4

1 に答える 1

7

ここでの問題は、コンバーターがhelloBean.currentSkinオブジェクトを埋める作業を行っていることですが、の値はこれに<h:inputText>バインドされており、サーバーに送信され、によってロードされた実際の値を置き換えます。言い換えると:helloBean.currentSkintitletextColorbackgroundColorStartconverter

  • helloBean.currentSkinコンバーターが実行され、選択された値に基づいてビルドされます。
  • <h:inputText id="name">空の値がサーバーに送信され、に挿入されhelloBean.currentSkin.titleます。他の2秒間も同じ動作です<h:inputText>
  • ビューは選択したものを使用してロードされ、空の値でhelloBean.currentSkinロードされます。helloBean.currentSkin.title他の2秒間も同じ動作です<h:inputText>

この問題には2つの解決策があります。

  1. をフォームの外に移動して<h:inputText>、空の値がサーバーに送信されないようにします。ビューをロードすると、コンバーターにロードされた値が維持されます。

    <h:form>
        <h:selectOneMenu id="dropdownSkin"
            value="#{helloBean.currentSkin}" defaultLabel="Select a skin.."
            valueChangeListener="#{helloBean.skinValueChanged}" immediate="true"
            onchange="this.form.submit()" converter="SkinConverter" >
            <f:selectItems value="#{helloBean.mySkinsSI}" var="c"
                itemValue="#{c.value}" />
        </h:selectOneMenu>
    </h:form>
    <br />
    <h:inputText id="name" value="#{helloBean.currentSkin.title}"></h:inputText>
    <!-- rest of Facelets code... -->
    
  2. helloBean.currentSkinドロップダウンリストで選択した値を変更しながらロードしているので、<f:ajax>内のタグコンポーネントを使用してajax動作を追加<h:selectOneMenu>し、フィールドをよりクリーンな方法で更新できます。私はこの解決策を選びます。

    <h:form>
        <!-- Note that there's no need of the onchange JavaScript function -->
        <h:selectOneMenu id="dropdownSkin"
            value="#{helloBean.currentSkin}" defaultLabel="Select a skin.."
            valueChangeListener="#{helloBean.skinValueChanged}" immediate="true"
            converter="SkinConverter" >
            <f:selectItems value="#{helloBean.mySkinsSI}" var="c"
                itemValue="#{c.value}" />
            <f:ajax process="@this" render="name tcolor bcolor" />
        </h:selectOneMenu>
        <br />
        <h:inputText id="name" value="#{helloBean.currentSkin.title}" />
        <h:inputText id="tcolor" value="#{helloBean.currentSkin.titleBar.textColor}" />
        <br />
        <h:inputText id="bcolor"
            value="#{helloBean.currentSkin.titleBar.backgroundColorStart}" />
    </h:form>
    

この<f:ajax>ようなオンラインチュートリアルで詳細を学ぶことができます。

ページでajax呼び出しを使用するため、マネージドBeanのスコープをから@SessionScopedに変更する必要があります@ViewScoped。これに関する詳細はこちら:JSF2でのコミュニケーション

于 2013-02-22T17:02:57.040 に答える