メインコンテンツまでスキップ

レコードへの値の反映

atPocket.app.record.set() でレコードに値を反映するときの動作をまとめます。

反映のタイミング

set()Promise を返します。代入は同期で行われ、名前解決を伴うものだけが非同期です。

同期(set() が戻った時点で反映済み)非同期(解決が完了するまで旧値)
通常フィールドの値連携フィールドのキー変更(value.value
選択系の labelValue連携フィールドの表示名検索(labelValue
リッチテキストの形式変換利用者選択・組織選択の管理コード(code)指定
連携フィールドのクリア(通常配置)明細の連携列(クリアを含む
利用者選択・組織選択のクリア([])・選択が変わらない場合明細の利用者選択列・組織選択列
明細の行構造(行数・行ID・並び)

覚えるルールは「名前解決をさせたなら await」の1つです。解決結果を参照しない既存のコードは、await を付けていなくてもそのまま動作します。

// 名前解決をさせない → await 不要
const record = atPocket.app.record.get();
record['field-1'].value = 'テキスト';
atPocket.app.record.set(record);

// 名前解決をさせた → 結果を参照するなら await
record['field-3'].labelValue = 'デモ株式会社';
await atPocket.app.record.set(record);
atPocket.app.record.get(); // 解決後の連携値が入っている
注意

setFieldDisabled / setFieldShown / setFieldStyle は DOM を操作するため、明細に行を追加した直後に追加行へ適用する場合は await が必要です(行の DOM は再描画後に生成されるため)。 行の見た目を決めるだけであれば、行データの中で disabled / visible / style を直接指定するほうが簡潔で、待ち合わせも不要です。

change イベントの発火(fireChange)

第2引数に { fireChange: true } を指定すると、値の反映後に app.record.{action}.change を発火できます。既定では発火しません。

await atPocket.app.record.set({ 'field-1': { value: 'A' } }, { fireChange: true });
項目内容
発火の対象値が実際に変化したフィールドのみ。同じ値をセットしても発火しません
対象外disabled / style / visible だけの変更(値の変更ではないため)
発火のタイミング連携フィールドの解決・明細の行の置換が完了したあと
明細明細フィールドのUID単位で1回のみ。列UIDでは発火しません
配送先登録済みのすべてのハンドラー。同じ画面の他のプラグインにも届きます

change イベントの changes.origin で、発火元が利用者の操作('user')か set()'set')かを判別できます。

atPocket.events.on('app.record.edit.change', (event) => {
if (event.changes.origin === 'set') return event; // set() 起因は無視する
// 利用者の操作のときだけ実行する処理
return event;
});

イベントハンドラーの中では実行できません

atPocket.events.on() のハンドラーの中から set() を呼び出すと例外を送出します。ハンドラーの中で値を変更するには、引数のイベントオブジェクトの record を書き換えて return してください。指定できる内容(value / style / editable / labelValue / lookup / disabled / visible)は set() と同じです。

// ✗ ハンドラーの中では実行できません
atPocket.events.on('app.record.edit.change', async (event) => {
await atPocket.app.record.set({ 'field-3': { value: '計算結果' } });
});

// ○ イベントオブジェクトを書き換えて return します
atPocket.events.on('app.record.edit.change', (event) => {
event.record['field-3'].value = '計算結果';
return event;
});

ボタンの onclick などハンドラーの外から呼ぶ set() は従来どおり利用できます。ハンドラーが return したあと(setTimeoutPromise の後続処理)も、ハンドラーの外側として扱われます。

連続して呼び出す場合の注意

同じフォームへの set()await で1つずつ呼び出してください
  • 解決中の明細へ次の set() で再び解決を伴う書き込みをすると、先行の解決(表示名・コピー先の反映)は破棄され、再解決されません。キーの代入は失われません。
  • Promise.all([set(a), set(b)]) のように並行して呼び出すと、互いの変更を打ち消したり、一部の change が発火しないことがあります。

解決の完了前に利用者が画面でフィールドやセルを編集した場合は、利用者の編集が優先されます。あとから返ってきた解決結果がその編集を上書きすることはありません。

関連ページ