1

こんにちは、私はjsf 2.1で遊んでいます

私は次のハンドラーを持っています

@Controller("testHandler")
@Scope("request")
public class TestHandler {

    public class EntityObject {

        public EntityObject(String value) {
            this.value = value;
        }

        private String value = "";

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            log.info(this + " Set value from " + this.value + " to " + value);
            this.value = value;
        }
    }

    private Logger log = Logger.getLogger(getClass());

    private List<EntityObject> objects = new ArrayList<TestHandler.EntityObject>();

    @PostConstruct
    public void init() {
        log.info("INIT");
        // addItem("O0");
        addItem("O1");
        addItem("O2");
        addItem("O3");
    }

    private void addItem(String name) {
        EntityObject e = new EntityObject(name);
        log.info("add " + e + " with value " + name);
        objects.add(e);
    }

    public List<EntityObject> getObjects() {
        return objects;
    }

    public void setObjects(List<EntityObject> objects) {
        this.objects = objects;
    }

}

そしてこのjsf

    <h:form>
        <h:dataTable value="#{testHandler.objects}" var="object">

            <h:column>
                <h:inputText value="#{object.value}" />
            </h:column>

        </h:dataTable>

        <h:commandButton value="submit" />
    </h:form>

私はTomcatをデバッグモードで実行しているので、コードをホットリプレースできます。

今、私はページを開いています

init | INIT
addItem | add TestHandler$EntityObject@41c3cce3 with value O1
addItem | add TestHandler$EntityObject@1dc06cd0 with value O2
addItem | add TestHandler$EntityObject@4427daf2 with value O3
  • 3つの入力フィールドを持つテーブルが表示されます
  • 各値の末尾に「変更」を追加します
  • 「addItem("O0");」のコメントを外します 初期化メソッドで
  • 送信ボタンを押します

->

init | INIT
addItem | add TestHandler$EntityObject@5d653eaa with value O0
addItem | add TestHandler$EntityObject@21f53acd with value O1
addItem | add TestHandler$EntityObject@6ae77a25 with value O2
addItem | add TestHandler$EntityObject@30449f8 with value O3
setValue | TestHandler$EntityObject@5d653eaa Set value from O0 to O1change
setValue | TestHandler$EntityObject@21f53acd Set value from O1 to O2change
setValue | TestHandler$EntityObject@6ae77a25 Set value from O2 to O3change

ログでは、以前に参照されたオブジェクトに値が割り当てられていないようです.jsfはリストのインデックスを記憶し、間違ったオブジェクトを更新しているようです.

オブジェクトの更新に最適な範囲は? 最新のリストと、テーブルからオブジェクトへの信頼できるマッピングをアーカイブするにはどうすればよいですか?

equals と hashcode 関数を追加しても役に立たなかった

4

2 に答える 2

0

実際、JSFは間違ったオブジェクトを更新していません。JSF2.0での有名な記事Communicationの引用

@RequestScoped:このスコープのBeanは、HTTP要求/応答が存続する限り存続します。HTTPリクエストで作成され、HTTPリクエストに関連付けられたHTTPレスポンスが終了すると破棄されます(これはajaxリクエストにも当てはまります!)。

したがって、「ヒット」ボタンを押すと、Beanは破棄されて作成されます。init中に、EntityObject配列が初期化されるため、状態を保存できません。

さまざまな種類のスコープのリンクを読んで、自分の興味に最も適したものを選択してください。特定のケースがない場合は、ViewScopedが役立つ場合があります。

于 2013-03-06T16:32:14.830 に答える
0

Request スコープを誤用しているようです。更新可能なデータには適していません。リクエスト スコープ内の Bean は、すべてのリクエスト (ボタン プッシュまたは AJAX 呼び出し) に対して作成されます。

送信ボタンを押すと、JSF は新しいリクエストを作成し、リクエスト スコープ Bean は破棄されます。しかし、同じページにとどまっているため、JSF DataTable Bean は破棄されず、すべてのコンポーネントを通過して値を更新します。

この時点で、JSF テーブル Bean には 3 つの InputText コンポーネントがあり、それらが更新されることに注意してください。リストの最初の 3 つの項目のみ。JSF はコンポーネントに完全なデータを保持せず (メモリの浪費)、参照のみを保持します。そこで面白いことに、2 番目の Init() で 2 つの項目を作成すると、JSF はエラーを返します。

ガイドライン付きのスコープの優れた説明は次のとおりです

参照: 適切な Bean スコープを選択するには?

于 2013-03-06T17:03:30.197 に答える