0

動的に作成されたデータテーブル (UIData) のフッター列 (UIColumn) に (UIInput) を追加しています。UIData は、jsp の datatable タグにバインドされます。データテーブルには、ヘッダーとフッターがあり、ヘッダーにはラベルがあり、フッターには編集可能なテキストボックスに対応する値があります。値を変更し、commandButton を使用してフォームを送信し、アクション メソッドで .getValue() を使用して UIInput 値にアクセスしようとすると、ページで更新された値ではなく、古い値が取得されます。バッキングBeanの属性にバインドしてみ、セッターに設定されている値を確認しました。古い値が設定されており、ページで更新した値がアクション メソッドまたはセッターに反映されていないことに気付きました。.getValue、.getLocalValue、.getSubmittedValue を使ってみました。これらのどれも私に新しい価値を与えません。


requestParameterMap から値を取得することで回避できました。問題の修正がある場合は、お知らせください。McDowell - ご意見ありがとうございます。

4

3 に答える 3

1

Tomcat では MyFaces 1.2.3、 Glassfish ではMojarra 2.0.0 Beta でデモ コードコードを実行しようとしましたが、問題を再現できませんでした。フィールドに入力した値が save() メソッドによって出力されました。

(MyFaces を使用するには、new UIData()new HtmlDataTable()に変更する必要がありました。これは、おそらくテーブル レンダラーの実装方法によるものですが、これは小さな変更です。)

Bean についていくつかの点に注意します。

  • テーブルゲッターは、呼び出されるたびに列を追加し続けます-サーバー側の状態を保存するページの更新のように
  • 通常、セッション Bean で UIComponent への参照を維持することはお勧めできません。コンポーネントバインディングにリクエストスコープを使用する方が良いでしょう
    • セッション Bean は Serializable を実装することになっています (ただし、誰もがそうしているわけではありません)。UIComponents はシリアライズできません。
    • ユーザーがページを 2 回開くと、コンポーネントが複数のビューになる可能性があります - 同時実行の問題
    • 仕様によると:JSFがビューを作成するとき、ゲッターを介してバインドされたコンポーネントを使用します。ただし、(送信時に)ビューを復元すると、セッターを介してコンポーネントが設定されるため、参照を保持することは(せいぜい)冗長です

ゲッターを次のように変更したい場合があります。

private UIData headerDataTable;

public UIData getHeaderDataTable() {
    if (headerDataTable == null) {
        headerDataTable = new UIData();
        getHeaderTable(headerDataTable);
    }
    return headerDataTable;
}

これらの変更で問題が解決するかどうかはわかりませんが、まだ問題が解決しない場合は、JSF 実装、バージョン、 web.xmlのjavax.faces.STATE_SAVING_METHODパラメータの値など、詳細を確認してもう一度お試しください(もしあれば)。

于 2009-06-11T22:58:52.253 に答える
0

実際のコードは他のいくつかの処理を行いますが、以下のコードは問題の再現に役立つはずです。以下のコードでは、TestString が変更された値をページから出力することを期待しています。しかし、それは古い値を返すだけです。以下はjspです:

<%@taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<html>
<head>
</head>
<f:view>
    <body>
        <h:form styleClass="form" id="form1">
            <h:commandButton value="Save" action="#{TestPageBackingBean.save}"  styleClass="commandExButton"/>
            <h:outputText styleClass="label" value="Header Table"/>
            <h:dataTable binding="#{TestPageBackingBean.headerDataTable}"></h:dataTable>
        </h:form>
    </body>
</f:view>
</html>

以下は顔の設定です:

<managed-bean>
    <managed-bean-name>TestPageBackingBean</managed-bean-name>
    <managed-bean-class>test.jsf.TestPageBackingBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean> 

以下は、バッキング Bean コードです。

package test.jsf;

import java.io.IOException;

import javax.faces.component.UIColumn;
import javax.faces.component.UIData;
import javax.faces.component.UIInput;
import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;

public class TestPageBackingBean {

  private UIData headerDataTable = new UIData();

  public TestPageBackingBean() {

  }

  public UIData getHeaderDataTable()
    {    
            return getHeaderTable(headerDataTable);
    }       

  public UIData getHeaderTable(UIData dataTable)
    {    
        for (int i=0;i<10;++i)
        {
            dataTable.getChildren().add(getColumn(i));
        }
        return dataTable;
    }

    private UIColumn getColumn(int i)
  {
    UIOutput outputLabelText = new UIOutput();
        UIInput inputFieldText = new UIInput(); 
        UIColumn column = new UIColumn();

        outputLabelText.setValue("Label" + i);
        inputFieldText.setValue("test input" + i);

        column.setHeader(outputLabelText);
        column.setFooter(inputFieldText);
        return column;
    }

    public String save() throws IOException {
            String TestString = "";
            FacesContext ctx = FacesContext.getCurrentInstance();
            if (!ctx.getResponseComplete()) {
                for (int i=0; i<headerDataTable.getChildren().size();++i)
                {
                    TestString = TestString + (String)((UIInput)((UIColumn) headerDataTable.getChildren().get(i)).getFooter()).getValue();
                }
             System.out.println(TestString);
            }
           return "save";
        }

    public void setHeaderDataTable(UIData headerDataTable) {
        this.headerDataTable = headerDataTable;
    }   
}
于 2009-06-11T17:49:10.143 に答える
0

この問題はまだ完全には解決されていません。

IBM JSF - Base Faces Support 7.0 および WAS 6.0 上の Enhanced Faces Components 7.0 で RSA 7 を使用しています。デフォルトでは、javax.faces.STATE_SAVING_METHOD は「サーバー」でした。

STATE_SAVING_METHOD を「client」に変更してみました。変更された値は出力に出力されましたが、変更した label0 ではなく label4 に出力されました。次の送信で、値が label4 から label8 に移動しました。矛盾しているように見えました。

于 2009-06-15T23:06:58.910 に答える