モデル駆動型アプリのフォーム OnSave イベント (クライアント API 参照)
イベントは次の場合に発生します: OnSave
- 保存する変更データがない場合でも、ユーザーはコマンド バーの [保存] ボタンまたは [更新] ボタンを選択します。
- 保存する変更されたデータがない場合でも、コードは formContext.data.entity.save メソッドを実行します。
- ユーザーがフォームから移動し、フォームに保存されていないデータがあります。
- 自動保存オプションが有効で、データ変更の 30 秒後にフォームに保存されていないデータがあります。
- コードは formContext.data.save メソッドを実行しますが、フォームには保存されていないデータがあります。
- コードは、最初のパラメータとしてtrue値を渡して formContext.data.refresh メソッドを実行しますが、フォームには保存されていないデータが存在します。
注意
予定、定期的な予定、またはサービス アクティビティ レコードのイベントは、保存操作を キャンセル し、orではなくメッセージを使用して変更を永続化します OnSave
。 Book
Create
Update
このため、 OnSave
および PostSave
これらのテーブルのイベント ハンドラーは機能しません。
保存を実行するためにどのボタンがクリックされたかを判断するには、 getSaveModeメソッド を使用します。
イベント引数オブジェクトの preventDefault メソッドを使用して、保存操作をキャンセルできます。 preventDefault メソッドには、実行コンテキストの一部である getEventArgs メソッドを使用してアクセスできます。 実行コンテキストは自動的にフォーム イベント ハンドラーに渡されます。
非同期イベント ハンドラー サポート
OnSaveイベントには、保存する前にイベント ハンドラーによって返されたプロミスが確定するのを待機する機能があり、 OnSave
イベントを非同期 ("async") にすることができます。
イベント ハンドラーがpromiseを返すと、イベントは非同期になります。 OnSave
OnSave
レコードの保存は、ハンドラーによって返された各プロミスが解決されたときに行われます。 返されるすべてのプロミスについて、各プロミス には 10 秒の制限があり、その後、プラットフォームはプロミスがタイムアウトしたと見なします。このタイムアウトは、プロミスごとに適用されます。 たとえば、5 つの promise が返された場合、合計待機時間は 50 秒です。
promise が拒否された、またはタイムアウトした場合、保存操作は引き続き現在のスクリプト エラーと同様に動作します。 スクリプト エラーやPromiseの拒否、またはハンドラーのタイムアウトが発生した場合に保存イベントが発生しないようにするには、特定のハンドラーのイベント引数オブジェクト内で preventDefault メソッドを使用します。
また、イベント引数オブジェクト内の preventDefault メソッドを使用して、ハンドラー内のエラーに関係なく、保存操作を キャンセル することもできます。 このメソッドが呼び出された場合、非同期 OnSave イベントはすべての promise が解決するまで待機しますが、保存は行われません。 このメソッドを呼び出すと、 .then()
& .catch()
内のロジックが実行されます。
OnSave
イベントは、ハンドラーごとに返される1つのプロミスを待機します。 複数のPromiseが必要な場合は、 Promise.all()
メソッド内のすべてのPromiseを ラップ し、結果として得られる単一のPromiseを返すことをお勧めします。 すべてが promise を返す複数のハンドラーでは、すべてのイベントを呼び出して、必要なすべての promise をラップする単一の promise を返す 1 つのハンドラーを作成することをお勧めします。 これによって、タイムアウトによる待機時間を最小限に抑えることができます。
非同期 OnSave ハンドラーを使用する場合のシナリオ例
作業指示書サービス タスクの作成を検討してください。選択した顧客資産に作業指示書に記載されているのと同じアカウントがあることを検証する必要があります。 作業指示書と顧客資産でのアカウントの取得はどちらも非同期プロセスであり、検証を行う前に完了する必要があります。
このシナリオでは、複数の非同期プロセスがあり、両方の呼び出しが Promise.all()
メソッドで両方をラップすることによって単一のpromiseを返します。
注意
preventDefault
メソッドは同期的にのみ使用できます。
例:
function myHandler() {
return Promise.all([getWorkOrderPromise, getCustomerAssetPromise]).then((values) => {
var workOrder = values[0];
var customerAsset = values[1];
// Perform validation
if (isValid(workOrder, customerAsset)) {
return Promise.resolve();
}
return Promise.reject(new Error("Validation failed for the work order and customer asset"));
});
}
アプリ設定を使用して非同期 OnSave を有効にする
非同期 onSave ハンドラーを使用するには、アプリの設定で有効にする必要があります:
https://make.powerapps.com に移動します。
正しい環境を選択するようにしてください。
左側のナビゲーション ウィンドウから、アプリを選択します。
アプリを 選択 し、次に 選択 ... (省略記号) を実行します。 編集 を選択します。
コマンド バーから、設定を選択します。
ダイアログが開いたら、選択 機能 を選択します。
非同期onSaveハンドラー をオンにします。
保存 を選びます。
非同期 OnSave タイムアウト
async OnSave
ハンドラーを使用すると、フォームはハンドラーによって返されたpromiseが満たされるまで待機します。 フォームの保存が適切なタイミングで完了するように、ハンドラーは10秒後にタイムアウト例外をスローし、パフォーマンスを向上させるためにasync OnSave
ハンドラーを調整するように通知します。
OnSave
ハンドラーを10秒以上一時停止する必要があるシナリオがあります。 例えば、ダイアログを開き、ユーザーの入力を待ってから保存を続行するような場合です。 非同期操作がPromiseの解決を待機するようにするには、 disableAsyncTimeout メソッドを使用します。
注意
awaitステートメントまたはasync呼び出しの前に、 disableAsyncTimeout
を呼び出す必要があります。
例:
async function myHandler(context) {
context.getEventArgs().disableAsyncTimeout();
// The 10000ms time out will not be disabled if the above line does not come before all async awaits
await Xrm.Navigation.openConfirmDialog({ text: "Are you sure you want to save?" });
}
disableAsyncTimeout が呼び出されると、そのハンドラーのタイムアウトは適用されません。 当該ハンドラーのプロミスが実行されるのを待機します。
このパターンはフォームの保存パフォーマンスに影響を与える可能性があるため、注意して使用する必要があります。
関連記事
グリッドOnSaveイベント
イベント (クライアントAPIリファレンス)
モデル駆動型アプリのフォームとグリッドのイベント