PowerAppsでちょっと凝ったアプリを作ろうと思うと、UpdateContextを多用することになると思いますが、意外ときれいな書き方をしている例が少ないのでまとめてみます。
複数のコンテキスト変数は1回でまとめて宣言する
UpdateContextはJSON形式で複数の変数を同時に指定可能なので、わざわざ変数ごとに都度UpdateContextを書く必要はありません。UpdateContextの内部は並列で処理されるため、変数が多い環境だと処理速度の向上も期待できそう。
冗長な例
UpdateContext({_message1: "Hoge"});
UpdateContext({_message2: "HogeHoge"});
UpdateContext({_message3: "HogeHogeHoge"});
クリーンな例(インデントはお好みで)
UpdateContext({
_message1: "Hoge",
_message2: "HogeHoge",
_message3: "HogeHogeHoge"
});
ただ、上述の通りUpdateContextは並列処理のため、宣言した変数を内部で直後に使用する事はできません。
UpdateContext({
i: 1,
j: 1+i // ← iの宣言前のため0とみなされ、1+0=1が代入されてしまう
});
上記のコードは、処理的には以下のコードとほぼ同義となります。
Concurrent(
UpdateContext({i:1}),
UpdateContext({j:i+1})
)
そのため、この場合はUpdateContext自体を分ける必要があります。
UpdateContext({i: 1});
UpdateContext({j: i+1}); // ← 正しく2が代入される
If文はUpdateContext内部で指定する
Ifによって変数に代入する値を変えたい場合は、UpdateContext内部で分岐させましょう。
冗長な例
If(flag,
UpdateContext({_message: "Hoge"}),
UpdateContext({_message: "HogeHoge"})
);
クリーンな例
UpdateContext({_message:
If(flag, "Hoge","HogeHoge")
});
初回表示時のみ変数を設定する場合は、Isblankで場合分けするのではなくCoalesce関数を使用する
最初にアクセスした際にのみ規定の値を変数に代入し、その後は現在の変数を保持したいという場合、Isblankで判定して代入する方法が一般的だと思います。
If(IsBlank(_message1), UpdateContext({_message1: "Hoge"}));
If(IsBlank(_message2), UpdateContext({_message2: "HogeHoge"}));
これも前述のようにUpdateContextでまとめたいところですが、キーと値の組み合わせはIf文で分岐できません。
//このコードはエラーが出て動作しません
UpdateContext({
If(IsBlank(_message1), _message1: "Hoge"),
If(IsBlank(_message2), _message2: "HogeHoge")
});
このような場合、IsBlankではなくCoalese関数を使うことで、クリーンに書くことができます。Coalese関数は、引数を順番に評価し、空白ではない最初の引数を返しますので、既に代入済みの場合はそのまま、代入されていない場合は第2引数に指定した値を代入します。
UpdateContext({
_message1: Coalesce(_message1, "Hoge"),
_message2: Coalesce(_message2, "HogeHoge")
});
おわりに
PowerAppsの記法については、まだまだベストプラクティスと言えるようなものはないので、今後も気が付き次第Qiitaにまとめていきたいと思います。