【UI5・CAP】OData V4でドラフト対応したアプリを作る (5)Side Effectsを使ってヘッダの合計金額を更新
はじめに
この記事は、OData V4でドラフト対応したアプリを作るシリーズの5回目です。
前回の記事で、CAPのイベントハンドラで明細金額が更新、または明細削除されたら、ヘッダのTotal Amountを更新する処理を実装しました。
しかし、現状では明細の数量、金額を更新すると明細の金額は更新されますがヘッダのTotal Amountは更新されません。
今回は、Side Effectsというテクニックを使い、明細の金額変更や削除と、ヘッダのTotal Amountが連動するようにしたいと思います。
ソースコードは以下に格納しています。
https://github.com/miyasuta/odata-v4-freestyle/tree/master/app/demo.bookingapp
Side Effectsとは
あるエンティティを更新したときに、関連するエンティティの項目も更新される場合があります。そんなとき、コンテキストのrequestSideEffects()というメソッドにより影響を受ける項目を再取得することができます。
参考:Initialization and Read Requests>Side Effects
別の方法としてバインディングのrefresh()メソッドを使うこともできますが、その場合バインドしている全ての情報を取り直すことになるため、目的に合わせて使い分ける必要があります。
UI5での実装
1. 明細金額が変更されたタイミングをとらえる
以下は明細テーブルのビュー定義です。
変更を検知したい項目(quantity, price)にfieldGroupIds
というプロパティを設定します。さらに、上位のコントロールであるColumnListItemでvalidateFieldGroup
というイベントにイベントハンドラを設定します。これで、quantityまたはpriceが変更されると、onValidate
というイベントハンドラが動くことになります。
参考:Field Groups
<ColumnListItem id="itemColumnListItem" validateFieldGroup="onValidate">
<Text text="{itemNumber}"/>
<Input value="{product}" editable="{viewModel>/editable}"/>
<Input value="{quantity}" editable="{viewModel>/editable}" fieldGroupIds="amount" />
<Input value="{price}" editable="{viewModel>/editable}" fieldGroupIds="amount"/>
<Text text="{amount}" />
</ColumnListItem>
onValidate: function (oEvent) {
var filedGroupId = oEvent.getSource().getFieldGroupIds()[0];
if (filedGroupId === "amount") {
this._requestTotalAmount(); //Side Effectsをリクエスト
}
},
2. 明細が削除されたタイミングをとらえる
明細の削除ボタンを押した際に動くイベントハンドラを使用します。
<Table id="itemTable"
items="{
path: 'to_items',
parameters: {
$orderby: 'itemNumber'
}}" mode="{= ${viewModel>/editable} ? 'Delete' : 'None'}" delete="onDeleteItem">
onDeleteItem: function (oEvent) {
oEvent.getParameter("listItem").getBindingContext().delete("$auto")
.then(()=> {
this._requestTotalAmount(); //Side Effectsをリクエスト
})
.catch(error => {
MessageBox.error(error.message, {});
})
},
3. Side Effectsをリクエスト
以下がSide Effectsをリクエストする処理です。コンテキストのrequestSideEffects()というメソッドを使用します。
_requestTotalAmount: function () {
this.getView().getObjectBinding().getBoundContext().requestSideEffects([{
$PropertyPath: "totalAmount"
}], "$auto");
},
一つ目の引数にはロードしたいプロパティまたはナビゲーションプロパティを指定します。配列で複数プロパティを指定することが可能です。プロパティの指定方法には以下のパターンがあります。
パターン | 意味 |
---|---|
{$PropertyPath : "TEAM_ID"} | プロパティ(単一項目)を指定 |
{$NavigationPropertyPath : "EMPLOYEE_2_MANAGER"} | ナビゲーションプロパティを指定(ナビゲーション先のエンティティ全体をロードする場合) |
{$PropertyPath : "EMPLOYEE_2_TEAM/Team_Id"} | ナビゲーション先のプロパティ(単一項目)を指定 |
二つ目の引数にはgroup IDを指定します。このパラメータは任意で、指定がない場合はコンテキストバインディングの更新用のグループID(デフォルトは"$auto")が使用されます。
4. 動作確認
明細更新や削除のタイミングでTotal Amountが更新されるようになりました。
明細更新
明細削除
ネットワークタブを見ると、明細を更新したタイミングで2つの$batchリクエストが飛んでいます。2つ目のリクエストがSide Effectsをロードするリクエストで、totalAmountの項目のみを取得していることがわかります。
まとめ
- あるエンティティを更新したときに、関連するエンティティの項目も更新される場合は、コンテキストのrequestSideEffects()というメソッドにより影響を受ける項目を再取得することができる。
- requestSideEffects()は指定した最小限の項目しかロードしないため、バインディングのrefresh()と比べてパフォーマンスが良い。
Author And Source
この問題について(【UI5・CAP】OData V4でドラフト対応したアプリを作る (5)Side Effectsを使ってヘッダの合計金額を更新), 我々は、より多くの情報をここで見つけました https://qiita.com/tami/items/e00883883cb0a7c293c7著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .