esmDevelopers
JSプラグイン
esm API
JSプラグイン
esm API
  • chainAPI

chainAPI

chainAPIはメソッドチェーンを用いて、自然言語的に JS プラグインを記述できるように設計された API です。
ScreenクラスのeventHook内で、useChainAPI関数から利用することができます。

esmJSPlugin.screen.sheetSave("schedule").onEntered(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");
  this.useChainAPI(function (chainAPI) {
    chainAPI
      .onUpdated(memoItem) // メモ項目の値が更新されたとき
      .setLabel(`メモ(${memoItem.length}文字)`) // ラベルを「`メモ(${memoItem.length}文字)`」に設定する
      .ifLengthIsGreaterThan(50) // もしメモ項目の文字数が50より大きければ
      .setLabelColor("red") // ラベルの色を赤色にする
      .else() // そうでなければ
      .setLabelColor(null); // ラベルの色をデフォルトの色にする
  });
});

基本概念

チェーン

chainAPIキーワードから始まる、メソッドチェーンで記述された一綴りの処理を JS プラグインではチェーンと呼びます。

esmJSPlugin.screen.sheetSave("schedule").onEntered(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");

  this.useChainAPI(function (chainAPI) {
    // チェーン1
    chainAPI.onMounted(memotItem).setLabel(`メモ(${memoItem.length}文字)`);

    // チェーン2
    chainAPI
      .onUpdated(memoItem)
      .setLabel(`メモ(${memoItem.length}文字)`)
      .ifLengthIsGreaterThan(50) // メモ項目の文字数が50より大きい場合
      .setLabelColor("red"); // ラベルの色を赤色にする
  });
});

シンタックス

前出の例では、chainAPIに対してonやif、setといった接頭辞で始まるメソッドを呼び出しているように見えますが、実際にchainAPIにこれらのメソッドがあるわけではなく、指定した対象のメソッド呼び出しを仲介しています。
これらのキーワードを JS プラグインでは便宜上シンタックスと呼びます。

例えば前出の例では、onシンタックスを利用してmemoItemのonMountedメソッドを呼び出しています。
また、ifシンタックスを利用してmemoItemのlengthIsGreaterThanメソッドを呼び出しています。
例の中ではifLengthIsGreaterThan(50)と記述されているので、memoItemを対象として指定していませんが、onシンタックスをはじめとするいくつかのシンタックスは、それ以後に記述される各シンタックスでの対象の指定を省略させることができます。

ブロック

チェーンは後述の、onおよびonEachシンタックスの以前・以後で分けられます。分けられたそれぞれを JS プラグインではブロックと呼びます。
onおよびonEachシンタックスはチェーン内でいずれかを一度しか利用できないので、チェーン内のブロック数は最大 2 となります。

esmJSPlugin.screen.sheetSave("schedule").onEntered(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");

  this.useChainAPI(function (chainAPI) {
    chainAPI
      // ブロック1
      .do(function () {
        console.log("do something");
      })
      .onMounted(memotItem)
      // ブロック2
      .setLabel(`メモ(${memoItem.length}文字)`);
  });
});

onおよびonEachシンタックス以前のブロックは、式の評価時点で即時実行されます。以後のブロックは、onおよびonEachメソッドの対象となるイベントが発生したタイミングで実行されます。
上記の例をchainAPIを使わずに書き下すと、以下のようになります。

esmJSPlugin.screen.sheetSave("schedule").onEntered(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");
  console.log("do something"); // ブロック1に該当
  memoItem.onMounted(function () {
    memoItem.setLabel(`メモ(${memoItem.length}文字)`); // ブロック2に該当
  });
});

利用可能シンタックス

on

onシンタックスは第一引数にTargetインスタンスをとり、処理の対象とします。
対象となるTargetインスタンスが持つ、onから始まるメソッド名を記述することで、対象インスタンスのメソッドを実行し、eventHookを登録します。
onシンタックス以後に記述された処理がイベント発生時に実行されるコールバック関数として登録されます。
第二引数以降は、メソッドの第二引数以降にマッピングされます。

チェーン内でonシンタックス以後に記述された各シンタックスは、第一引数での対象の指定がされなかった場合、onシンタックスで指定された対象を処理の対象として扱います。
また、doやif等の単一のコールバック関数を受け取るシンタックスの場合は、同じく、onシンタックスで指定された対象がコールバック関数の引数として渡されます。

esmJSPlugin.screen.sheetSave("schedule").onEntered(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");

  this.useChainAPI(function (chainAPI) {
    // メモ項目が初期化されたときに、ラベルの色を赤にする
    chainAPI
      .onMounted(memoItem)
      .setLabelColor("red");
  });
});

上記の例をchainAPIを使わずに書き下すと、以下のようになります。

esmJSPlugin.screen.sheetSave("schedule").onEntered(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");

  memoItem.onMounted(function () {
    // メモ項目が初期化されたときに、ラベルの色を赤にする
    memoItem.setLabelColor("red");
  });
});

Important

  • onシンタックスは第一引数に必ずTargetインスタンスを指定する必要があります。
  • onシンタックスおよびonEachシンタックス(後述)はチェーン内でいずれかを一度しか使用できません。

onEach

onEachシンタックスは第一引数にTargetsインスタンスをとり、処理の対象とします。
対象となるTargetsインスタンスが内包するTargetインスタンスが持つ、onから始まるメソッド名を記述することで、それぞれのTargetインスタンスに対してメソッドを実行し、eventHookを登録します。
onEachシンタックス以後に記述された処理がイベント発生時に実行されるコールバック関数として登録されます。
第二引数以降は、メソッドの第二引数以降にマッピングされます。

チェーン内でonEachシンタックス以後に記述された各シンタックスは、第一引数での対象の指定がされなかった場合、onEachシンタックスで指定されたTargetsインスタンスが内包する各Targetインスタンスを処理の対象として扱います。
また、doやif等の単一のコールバック関数を受け取るシンタックスの場合は、同じく、onEachシンタックスで指定されたTargetsインスタンスが内包する各Targetインスタンスがコールバック関数の引数として渡されます。

esmJSPlugin.screen.sheetSave("schedule").onEntered(function (screen) {
  const sheetItems = screen.getSheetItems();

  this.useChainAPI(function (chainAPI) {
    // 値が変更された項目のラベルを赤色に変更する
    chainAPI
      .onEachUpdated(sheetItems)
      .setLabelColor("red");
  });
});

上記の例をchainAPIを使わずに書き下すと、以下のようになります。

esmJSPlugin.screen.sheetSave("schedule").onEntered(function (screen) {
  const sheetItems = screen.getSheetItems();

  // eventHook登録済みの項目インスタンスを保持
  const registeredHooks = [];

  sheetItems.onMounted(function () {
    // 初期化時に表示されている項目のeventHook登録
    sheetItems.entities.forEach(function (sheetItem) {
      const unregister = sheetItem.onUpdated(function () {
        sheetItem.setLabelColor("red");
      });
      registeredHooks.push({ item: sheetItem, unregister });
    });
  });

  sheetItems.onUpdated(function () {
    // 表示項目の変更によって不要になったeventHookの解除
    const deletedHooks = registeredHooks.filter(function ({ item }) {
      return !sheetItems.entities.includes(item);
    });
    deletedHooks.forEach(function ({ unregister }) {
      unregister();
    });
    registeredHooks = registeredHooks.filter(function (hook) {
      return !deletedHooks.includes(hook);
    });

    // 表示項目の変更によって追加された項目のeventHook登録
    const registeredItems = registeredHooks.map(function ({ item }) {
      return item;
    });
    const addedItems = sheetItems.entities.filter(function (sheetItem) {
      return !registeredItems.includes(sheetItem);
    });
    addedItems.forEach(function (addedItem) {
      const unregister = addedItem.onUpdated(function () {
        addedItem.setLabelColor("red");
      });
      registeredHooks.push({ item: addedItem, unregister });
    });
  });
});

Important

  • onEachシンタックスは第一引数に必ずTargetsインスタンスを指定する必要があります。
  • onシンタックス(前述)およびonEachシンタックスはチェーン内でいずれかを一度しか使用できません。

do

doシンタックスはコールバック関数を引数にとり、実行します。
onまたはonEachシンタックス以後にdoシンタックスが記述されている場合、コールバック関数の引数にはonまたはonEachシンタックスで束縛されたTargetインスタンスが渡されます。

esmJSPlugin.screen.sheetSave("schedule").onEntered(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");

  this.useChainAPI(function (chainAPI) {
    chainAPI.do(function () {
      console.log("do something");
    });

    // メモ項目の値が更新されたときに、ラベルを出力
    chainAPI
      .onUpdated(memoItem)
      .do(function (item) {
        console.log(item.label);
      });
  });
});

上記の例をchainAPIを使わずに書き下すと、以下のようになります。

esmJSPlugin.screen.sheetSave("schedule").onEntered(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");

  console.log("do something");
  memoItem.onUpdated(function () {
    // メモ項目の値が更新されたときに、ラベルを出力
    console.log(memoItem.label);
  });
});

set

setシンタックスは第一引数にTargetインスタンスをとり、処理の対象とします。
対象となるTargetインスタンスが持つ、setから始まるメソッド名を記述することで、対象インスタンスのメソッドを実行します。
対象以降の引数は、実行メソッドの引数にマッピングされます。

esmJSPlugin.screen.sheetUpdate("schedule").onSheetItemsMounted(function (screen) {
    const memoItem = screen.getSheetItem("calendar.schedule.memo");
    this.useChainAPI(function (chainAPI) {
      chainAPI
        .setLabel(memoItem, `メモ(${memoItem.length}文字)`);

      chainAPI
        .onUpdated(memoItem)
        .setLabel(`メモ(${memoItem.length}文字)`); // onの対象と同じ場合、setシンタックスの対象の指定は省略可能
    });
  });

上記の例をchainAPIを使わずに書き下すと、以下のようになります。

esmJSPlugin.screen.sheetUpdate("schedule").onSheetItemsMounted(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");

  memoItem.setLabel(`メモ(${memoItem.length}文字)`);

  unregister = memoItem.onUpdated(function () {
    memoItem.setLabel(`メモ(${memoItem.length}文字)`);
  });
});

if

ifシンタックスは第一引数にTargetインスタンスをとり、処理の対象とします。
対象となるTargetインスタンスが持つ、返値として真偽値を返すメソッドに接頭辞としてifを付与して記述することで、対象インスタンスのメソッドを実行し、後に続く処理を条件付きで実行することができます。
対象以降の引数は、実行メソッドの引数にマッピングされます。

esmJSPlugin.screen.sheetUpdate("schedule").onSheetItemsMounted(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");
  this.useChainAPI(function (chainAPI) {
    chainAPI.ifLengthIsGreaterThanOrEqual(memoItem, 50).do(function () {
      console.log("50文字以上");
    });

    chainAPI
      .onUpdated(memoItem)
      .ifLengthIsLessThan(50) // onの対象と同じ場合、ifシンタックス対象の指定は省略可能
      .do(function () {
        console.log("50文字未満");
      });
  });
});

上記の例をchainAPIを使わずに書き下すと、以下のようになります。

esmJSPlugin.screen.sheetUpdate("schedule").onSheetItemsMounted(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");

  if (memoItem.lengthIsGreaterThanOrEqual(50)) {
    console.log("50文字以上");
  }

  unregister = memoItem.onUpdated(function () {
    if (memoItem.lengthIsLessThan(50)) {
      console.log("50文字未満");
    }
  });
});

また、ifシンタックスは対象を指定せず、真偽値を返す任意のコールバック関数を引数とすることもできます。
このとき、onまたはonEachシンタックス以後にifシンタックスが記述されている場合、コールバック関数の引数にはonまたはonEachシンタックスで束縛されたTargetインスタンスが渡されます。

esmJSPlugin.screen.sheetUpdate("schedule").onEntered(function (screen) {
  const sheetItems = screen.getSheetItems();

  this.useChainAPI(function (chainAPI) {
    chainAPI
      // コールバック関数を利用
      .if(function () {
        return true;
      })
      .do(function () {
        console.log("do something");
      });

    chainAPI
      .onEachMounted(sheetItems)
      // コールバック関数を利用
      // 引数にはonEachMountedで指定したTargetsインスタンスの各要素が渡される
      .if(function (sheetItem) {
        return sheetItem.label.includes("substring");
      })
      .do(function () {
        console.log("do something");
      });
  });
});

Important

ifシンタックスはブロック内で一度しか使用できません。

elseif

elseifシンタックスは第一引数にTargetインスタンスをとり、処理の対象とします。
対象となるTargetインスタンスが持つ、返値として真偽値を返すメソッドに接頭辞としてelseifを付与して記述することで、対象インスタンスのメソッドを実行します。
ブロック内のこれ以前に記述されたifやelseifシンタックスの条件を満たさず、かつ、このシンタックスで指定された条件を満たす場合にのみ、後に続く処理を実行することができます。
ブロック内で、ifシンタックス以後にしか記述できません。また、elseシンタックス以後には記述できません。
対象以降の引数は、実行メソッドの引数にマッピングされます。

esmJSPlugin.screen.sheetUpdate("schedule").onSheetItemsMounted(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");
  this.useChainAPI(function (chainAPI) {
    chainAPI
      .ifLengthIsGreaterThanOrEqual(memoItem, 50)
      .do(function () {
        console.log("50文字以上");
      })
      .elseifLengthIsGreaterThanOrEqual(memoItem, 40)
      .do(function () {
        console.log("40文字以上");
      });

    chainAPI
      .onUpdated(memoItem)
      .ifLengthIsLessThan(50)
      .do(function () {
        console.log("50文字未満");
      })
      .elseifLengthIsLessThan(60) // onの対象と同じ場合、elseifシンタックスの対象の指定は省略可能
      .do(function () {
        console.log("60文字未満");
      });
  });
});

上記の例をchainAPIを使わずに書き下すと、以下のようになります。

esmJSPlugin.screen.sheetUpdate("schedule").onSheetItemsMounted(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");

  if (memoItem.lengthIsGreaterThanOrEqual(50)) {
    console.log("50文字以上");
  } else if (memoItem.lengthIsGreaterThanOrEqual(40)) {
    console.log("40文字以上");
  }

  unregister = memoItem.onUpdated(function () {
    if (memoItem.lengthIsLessThan(50)) {
      console.log("50文字未満");
    } else if (memoItem.lengthIsLessThan(60)) {
      console.log("60文字未満");
    }
  });
});

また、elseifシンタックスは対象を指定せず、真偽値を返す任意のコールバック関数を引数とすることもできます。
このとき、onまたはonEachシンタックス以後にelseifシンタックスが記述されている場合、コールバック関数の引数にはonまたはonEachシンタックスで束縛されたTargetインスタンスが渡されます。

esmJSPlugin.screen.sheetUpdate("schedule").onEntered(function (screen) {
  const sheetItems = screen.getSheetItems();

  this.useChainAPI(function (chainAPI) {
    chainAPI
      .if(function () {
        return false;
      })
      .do(function () {
        console.log("do something");
      })
      // コールバック関数を利用
      .elseif(function () {
        return true;
      })
      .do(function () {
        console.log("do something else");
      });

    chainAPI
      .onEachMounted(sheetItems)
      .if(function () {
        return false;
      })
      .do(function () {
        console.log("do something");
      })
      // コールバック関数を利用
      // 引数にはonEachMountedで指定したTargetsインスタンスの各要素が渡される
      .elseif(function (sheetItem) {
        return sheetItem.label.includes("substring");
      })
      .do(function () {
        console.log("do something else");
      });
  });
});

else

elseシンタックスは引数をとりません。
ブロック内のこれ以前に記述されたifやelseifシンタックスの条件を満たさなかった場合にのみ、後に続く処理を実行することができます。
ブロック内で、ifシンタックス以後にしか記述できません。

esmJSPlugin.screen.sheetSave("schedule").onEntered(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");
  this.useChainAPI(function (chainAPI) {
    chainAPI
      .onUpdated(memoItem)
      .ifLengthIsGreaterThan(50)
      .setLabelColor("red")
      .else()
      .setLabelColor(null);
  });
});

上記の例をchainAPIを使わずに書き下すと、以下のようになります。

esmJSPlugin.screen.sheetSave("schedule").onEntered(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");

  memoItem.onUpdated(function () {
    if (memoItem.lengthIsGreaterThan(50)) {
      memoItem.setLabelColor("red");
    } else {
      memoItem.setLabelColor(null);
    }
  });
});

Important

elseシンタックスはブロック内で一度しか使用できません。

or

orシンタックスは第一引数にTargetインスタンスをとり、処理の対象とします。
対象となるTargetインスタンスが持つ、返値として真偽値を返すメソッドに接頭辞としてorを付与して記述することで、対象インスタンスのメソッドを実行します。
ブロック内の直前に記述されたifやelseif、or、andシンタックスとの論理和をとって、条件を満たす場合にのみ後に続く処理を実行することができます。
対象以降の引数は、実行メソッドの引数にマッピングされます。

esmJSPlugin.screen.sheetUpdate("schedule").onSheetItemsMounted(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");
  this.useChainAPI(function (chainAPI) {
    chainAPI
      .ifLengthIsGreaterThanOrEqual(memoItem, 50)
      .orLengthIsLessThanOrEqual(memoItem, 40)
      .do(function () {
        console.log("50文字以上または40文字以下");
      });

    chainAPI
      .onUpdated(memoItem)
      .ifLengthIsGreaterThanOrEqual(50)
      .orLengthIsLessThanOrEqual(40) // onの対象と同じ場合、ifシンタックス対象の指定は省略可能
      .do(function () {
        console.log("50文字以上または40文字以下");
      });
  });
});

上記の例をchainAPIを使わずに書き下すと、以下のようになります。

esmJSPlugin.screen.sheetUpdate("schedule").onSheetItemsMounted(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");

  if (memoItem.lengthIsGreaterThanOrEqual(50) || memoItem.lengthIsLessThanOrEqual(40)) {
    console.log("50文字以上または40文字以下");
  }

  unregister = memoItem.onUpdated(function () {
    if (memoItem.lengthIsGreaterThanOrEqual(50) || memoItem.lengthIsLessThanOrEqual(40)) {
      console.log("50文字以上または40文字以下");
    }
  });
});

また、orシンタックスは対象を指定せず、真偽値を返す任意のコールバック関数を引数とすることもできます。
このとき、onまたはonEachシンタックス以後にorシンタックスが記述されている場合、コールバック関数の引数にはonまたはonEachシンタックスで束縛されたTargetインスタンスが渡されます。

esmJSPlugin.screen.sheetUpdate("schedule").onEntered(function (screen) {
  const sheetItems = screen.getSheetItems();

  this.useChainAPI(function (chainAPI) {
    chainAPI
      .if(function () {
        return false;
      })
      // コールバック関数を利用
      .or(function () {
        return true;
      })
      .do(function () {
        console.log("do something");
      });

    chainAPI
      .onEachMounted(sheetItems)
      .if(function () {
        return false;
      })
      // コールバック関数を利用
      // 引数にはonEachMountedで指定したTargetsインスタンスの各要素が渡される
      .or(function (sheetItem) {
        return sheetItem.label.includes("substring");
      })
      .do(function () {
        console.log("do something");
      });
  });
});

and

andシンタックスは第一引数にTargetインスタンスをとり、処理の対象とします。
対象となるTargetインスタンスが持つ、返値として真偽値を返すメソッドに接頭辞としてandを付与して記述することで、対象インスタンスのメソッドを実行します。
ブロック内の直前に記述されたifやelseif、or、andシンタックスとの論理積をとって、条件を満たす場合にのみ後に続く処理を実行することができます。
対象以降の引数は、実行メソッドの引数にマッピングされます。

esmJSPlugin.screen.sheetUpdate("schedule").onSheetItemsMounted(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");
  this.useChainAPI(function (chainAPI) {
    chainAPI
      .ifLengthIsGreaterThanOrEqual(memoItem, 50)
      .andLengthIsLessThanOrEqual(memoItem, 60)
      .do(function () {
        console.log("50文字以上かつ60文字以下");
      });

    chainAPI
      .onUpdated(memoItem)
      .ifLengthIsGreaterThanOrEqual(50)
      .andLengthIsLessThanOrEqual(60) // onの対象と同じ場合、ifシンタックス対象の指定は省略可能
      .do(function () {
        console.log("50文字以上かつ60文字以下");
      });
  });
});

上記の例をchainAPIを使わずに書き下すと、以下のようになります。

esmJSPlugin.screen.sheetUpdate("schedule").onSheetItemsMounted(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");
  if (memoItem.lengthIsGreaterThanOrEqual(50) && memoItem.lengthIsLessThanOrEqual(60)) {
    console.log("50文字以上かつ60文字以下");
  }

  memoItem.onUpdated(function () {
    if (memoItem.lengthIsGreaterThanOrEqual(50) && memoItem.lengthIsLessThanOrEqual(60)) {
      console.log("50文字以上かつ60文字以下");
    }
  });
});

また、andシンタックスは対象を指定せず、真偽値を返す任意のコールバック関数を引数とすることもできます。
このとき、onまたはonEachシンタックス以後にandシンタックスが記述されている場合、コールバック関数の引数にはonまたはonEachシンタックスで束縛されたTargetインスタンスが渡されます。

esmJSPlugin.screen.sheetUpdate("schedule").onEntered(function (screen) {
  const sheetItems = screen.getSheetItems();

  this.useChainAPI(function (chainAPI) {
    chainAPI
      .if(function () {
        return true;
      })
      // コールバック関数を利用
      .and(function () {
        return true;
      })
      .do(function () {
        console.log("do something");
      });

    chainAPI
      .onEachMounted(sheetItems)
      .if(function () {
        return true;
      })
      // コールバック関数を利用
      // 引数にはonEachMountedで指定したTargetsインスタンスの各要素が渡される
      .and(function (sheetItem) {
        return sheetItem.label.includes("substring");
      })
      .do(function () {
        console.log("do something");
      });
  });
});

not

notシンタックスはifやelseif、or、andシンタックスとあわせて利用します。
ifやelseif、or、andの後にNotを付与して記述することで、指定された条件を満たさない場合にのみ、後に続く処理を実行することができます。

esmJSPlugin.screen.sheetUpdate("schedule").onSheetItemsMounted(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");
  this.useChainAPI(function (chainAPI) {
    chainAPI
      .ifNotLengthIsGreaterThanOrEqual(memoItem, 50)
      .do(function () {
        console.log("50文字未満");
      });

    chainAPI
      .ifLengthIsGreaterThanOrEqual(memoItem, 50)
      .andNotLengthIsGreaterThan(memoItem, 60)
      .do(function () {
        console.log("50文字以上かつ60文字以下");
      });
  });
});

上記の例をchainAPIを使わずに書き下すと、以下のようになります。

esmJSPlugin.screen.sheetUpdate("schedule").onSheetItemsMounted(function (screen) {
  const memoItem = screen.getSheetItem("calendar.schedule.memo");

  if (!memoItem.lengthIsGreaterThanOrEqual(50)) {
    console.log("50文字未満");
  }

  if (memoItem.lengthIsGreaterThanOrEqual(50) && !memoItem.lengthIsGreaterThan(60)) {
    console.log("50文字以上かつ60文字以下");
  }
});

each

eachシンタックスは引数にTargetsインスタンスをとります。
指定したTargetsインスタンスが内包する各Targetインスタンスが、ブロック内のeachシンタックス以後のシンタックスの処理の対象となります。 また、doやif等の単一のコールバック関数を受け取るシンタックスの場合は、同じく、onEachシンタックスで指定されたTargetsインスタンスが内包する各Targetインスタンスがコールバック関数の引数として渡されます。

esmJSPlugin.screen.sheetSave("businessplan").onSheetItemsMounted(function (screen) {
  const sheetItems = screen.getSheetItems();

  this.useChainAPI(function (chainAPI) {
    chainAPI
      .each(sheetItems)
      .do(function (sheetItem) {
        console.log(sheetItem.label);
      })
      // 業務タイプ切り替え等により表示項目が切り替わるたびに、表示されている全ての項目のラベルを出力する
      .onUpdated(sheetItems)
      .each(sheetItems)
      .do(function (sheetItem) {
        console.log(sheetItem.label);
      });
  });
});

上記の例をchainAPIを使わずに書き下すと、以下のようになります。

esmJSPlugin.screen.sheetSave("businessplan").onSheetItemsMounted(function (screen) {
  const sheetItems = screen.getSheetItems();

  sheetItems.entities.forEach(function (sheetItem) {
    console.log(sheetItem.label);
  });

  sheetItems.onUpdated(function () {
    sheetItems.entities.forEach(function () {
      console.log(sheetItem.label);
    })
  })
});

Important

  • eachシンタックスはブロック内で一度しか使用できません
  • eachシンタックスはonEachシンタックスの後に使用することはできません。

eventHook のクリーンアップ

画面に遷移してから離れるまでに複数回発生するようなイベントに対して、ScreenインスタンスのeventHookを登録する場合などは、適切なクリーンアップ処理が必要でした。
chainAPIでは、ScreenインスタンスのeventHookが実行されるたびに、chainAPIによって登録されたeventHookが自動的に解除されるのでクリーンアップ処理は不要です。

let unregister;

// 顧客タイプの切り替えによって表示する項目が変更されるたびに実行される
esmJSPlugin.screen.sheetSave("customer").onSheetItemsUpdated(function (screen) {
  // 前回のonSheetItemsUpdatedで登録されたcustomerNameItemに対するeventHookがあれば解除
  if (unregister) {
    unregister();
  }

  const customerNameItem = screen.getSheetItemByLabel("顧客名");

  unregister = customerNameItem.onMounted(function () {
    // 顧客登録変更画面で、顧客名項目初期化時に値を出力する
    console.log(customerNameItem.value);
  });
});

chainAPIを利用しない上記の例では、クリーンアップ処理が必要でした。

// 顧客タイプの切り替えによって表示する項目が変更されるたびに実行される
esmJSPlugin.screen.sheetSave("customer").onSheetItemsUpdated(function (screen) {
  const customerNameItem = screen.getSheetItemByLabel("顧客名");

  this.useChainAPI(function (chainAPI) {
    chainAPI.onMounted(customerNameItem).do(function () {
      // 顧客登録変更画面で、顧客名項目初期化時に値を出力する
      console.log(customerNameItem.value);
    });
  });
});

chainAPIでは、onSheetItemsUpdatedのコールバック関数を実行されるたびに、前回実行時にchainAPIにより登録されたcustomerNameItemのeventHookが自動的に解除されるため、クリーンアップ処理は不要です。