2017-12-12 18 views
0

モデルオブジェクトのフィールドにバインドされたテキストフィールド入力を含むフォームがあります。ユーザーがそのテキストフィールドにデータを入力すると、計算に基づいてフォーム内の複数の他のフィールド/コンポーネントに影響を与える可能性があります。私のビジネスロジックはサービスレイヤーにカプセル化されています。モデルの変更/再レンダリングでビューを同期する方法

理論的には、ユーザーがフィールドを更新すると、サービスのロジックが適用され、影響を受けるすべてのフィールドがモデル上で更新されるサーバー(キー押し時)にajax呼び出しが行われるオブジェクト。モデルがサーバー上で更新されたら、モデルオブジェクトの現在の状態を画面に同期させたいと思います。

これを実行して画面全体をリフレッシュする唯一の方法はありますか?変更されたモデルのフィールドにバインドされたコンポーネントだけを再レンダリングする方法はありますか?また、画面を更新すると、編集中のフィールドも更新されますが、これを除外する方法はありますか?

このテクニックのベストプラクティスに興味があります。 Ajaxで

おかげ

+0

AJAX応答コールバックから呼び出されるJavascriptを使用してフィールドを更新することをお勧めします。 – tsolakp

答えて

1

あなたはちょうどそれがマークアップID(Component.setOutputMarkupId(true))を持っていることを確認し、必要なすべてのコンポーネントを更新することができます。

あなたはAjaxFormComponentUpdatingBehaviorまたはAjaxFormChoiceComponentUpdatingBehaviorを使用する必要があるとそのonUpdate()コールバックで、あなたがそれぞれのFormComponent秒のモデルを更新する必要があり、その後、あなたは、現在のフォームのすべてのFormComponentsを訪問し、AjaxRequestTargetにあなたが持っているものだけを追加するためにFormComponent.this.getForm().visitChildren(FormComponent.class, IVisit)を使用することができます更新しました。

更新 もう一つの良い解決方法は、Wicketイベントバスを使用することです。 Ajaxの振る舞いでは、イベントをブロードキャストすることができます:

component.send(getForm(), Broadcast.BREADTH, new UIChangedEvent(target, newValue)); 

UIChangedEventが更新されたコンポーネントとAjaxRequestTargetの新しい価値をもたらす独自のクラス/ POJOです。

他のFormComponentsは#onEvent()をオーバーライドし、その値を使用して新しい値を計算し、以前の計算に応じてターゲットを使用して更新するかどうかを指定できます。

+0

私が本当に好きなのは、ビューを再レンダリングすることですが、画面上にあるものとは異なる値を持つフィールドだけを明示的に作成する必要はありません。たとえば、 "onupdate changeフィールドA、B、C、F、X "を含む。更新されたものだけを追加することを提案している場合は、どのフィールドが更新されるのかを確認する方法がありますか?または、元のモデルへの参照を持ってフィールドごとに比較フィールドを作成する必要がありますか? – kgrad

+0

私の更新された答えを見てください。これで十分ですね! –

+1

こんにちはマーティン、個人的に私は新しい価値観を持つ出来事を嫌います。私は彼らがコンポーネントによって適切なモデルに自分自身で設定されるべきだと思います。イベントは、モデル上で動作するコンポーネント(または派生モデル)によって処理され、これらのコンポーネントはモデル内のデータを再利用する必要があります。これにより、 'モデルのバグを更新する担当者'は除かれます – RobAu

1

私は自分のタグからあなたが改札を使用していると仮定します。 Wicketは、この目的のためにBehaviorsを使用します。次の例では、TextFieldの入力が変更された場合に両方のDropDownChoicesを更新します。それらのコントロールをAjaxRequestTargetに追加するだけです。両方のDropDownChoicesのモデルがフロントエンドでリロードされ、再レンダリングされます。また、更新するコントロールに対してsetOutputMarkupId(true)を呼び出すようにしてください。

TextField<String> textField = new TextField<String>("input"); 
    Component dropDownA = new DropDownChoice<>("dropA").setOutputMarkupId(true); 
    Component dropDownB = new DropDownChoice<>("dropB").setOutputMarkupId(true); 

    textField.add(new AjaxFormComponentUpdatingBehavior("change") { 
     private static final long serialVersionUID = 1478280524536023725L; 

     @Override 
     protected void onUpdate(AjaxRequestTarget target) { 
      target.add(dropDownA); 
      target.add(dropDownB); 
     } 
    }); 
+0

イベントタイプは 'on'プレフィックスなしで指定する必要があります。したがって、この場合は 'onchange'の代わりに' change'だけです。 Wicket 7の 'AjaxEventBehavior'の次の警告を参照してください:"バージョン6.0.0以降、WicketはJavaScriptイベント登録を使用していますので、イベント名 '%s'の先頭に 'on'は必要ありません。 Wicket 8.xは提供されたイベント名を操作しないので、先頭の 'on'がアプリケーションを壊す可能性があります。 – Tekki

+0

情報ありがとうございます。私はそれについて気づいていなかったし、その声明を変更した。 –

関連する問題