no versions found for ApplicationFrameworkReferences / Components/View/ProtoViewLogic/protoviewlogic_relateElements / en

ProtoViewLogic: relateElements()

HTML 要素を対象の ProtoViewLogic に関連づけます。関連付けられた要素は自身に対するイベントをその ProtoViewLogic へ通知するようになります。

この関数は引数 elementMap がプロミスでなければ同期関数、プロミスであれば非同期関数です。

構文

protoViewLogic.relateElements(elementMap) => object | Promise<object>

引数

  • elementMap: object | Promise<object>

    関連付ける要素とその名前を対応づけるオブジェクト、または履行時にそれを与える Promise です。

    各プロパティは Element インスタンスか ProtoViewLogic インスタンスの配列です。

    それぞれのプロパティ名は対象の ViewLogic インスタンスに追加するプロパティの名前として使われます。

返値: object | Promise<object>

引数 elementMap が与えるオブジェクトのうち、対象の ProtoViewLogic に関連づけられなかったプロパティを持つオブジェクト、または履行時にそれを与える Promise です。

オブジェクトは elementMap が与えるオブジェクトのコピーであり、elementMap として渡したオブジェクト自体は変更されません。

例外

  • SyntaxError
    • 引数 elementMapPromise でなく、そのプロパティ名に、識別子として使用できない文字が含まれている場合。
    • 引数 elementMapPromise でなく、そのプロパティ名に、プロトタイプに定義済みの名前が指定されている場合
  • TypeError
    • 引数 elementMapPromise でなく、Element または Array<Element> 以外のプロパティを持つ場合
    • 引数 elementMapProtoViewLogic のインスタンスである場合
  • ReferenceError
    • 引数 elementMapPromise でなく、所有権情報の壊れた Element を持つ場合
    • 引数 elementMapPromise でなく、複数のプロパティが同一のオブジェクトへの参照を持つ場合

const honest = new class extends ProtoViewLogic {
    async messageHandler(msg) {
        msg.deliver({
            buttonOk: (msg) => {
                console.log("The honest said \"OK!\" and of course it's truely true.");
            },
            buttonCancel: (msg) => {
                console.log("The honest said \"cancelled!\" and of course it's truely true.");
            },
        });
    }
};
const liar = new class extends ProtoViewLogic {
    async messageHandler(msg) {
        msg.deliver({
            buttonOk: (msg) => {
                console.log("The liar said \"cancelled!\" but of course it's definitely untrue.");
            },
            buttonCancel: (msg) => {
                console.log("The liar said \"OK!\" but of course it's definitely untrue.");
            },
        });
    }
};
const buttonOk      = document.createElement("button");
const buttonCancel  = document.createElement("button");
buttonOk.setAttribute("id", "button-ok");
buttonOk.setAttribute("data-active-events", "click");
buttonOk.textContent = "OK";
buttonCancel.setAttribute("id", "button-cancel");
buttonCancel.setAttribute("data-active-events", "click");
buttonCancel.textContent = "CANCEL";

document.body.append(buttonOk, buttonCancel);

honest.relateElements({ buttonOk: buttonOk, buttonCancel: buttonCancel });
buttonOk.click();
// ==> "The honest said \"OK!\" ... "
buttonCancel.click();
// ==> "The honest said \"cancelled!\" ... "

liar.relateElements({ buttonOk: buttonOk, buttonCancel: buttonCancel });
buttonOk.click();
// ==> "The liar said \"cancelled!\" ... "
buttonCancel.click();
// ==> "The liar said \"OK!\" ... "

解説

呼び出し先の ProtoViewLogicelementMap のプロパティをを割り当てます。

例えば、vl: ProtoViewLogic に対して elementMap.foo: Element が定義されたオブジェクトを渡してこの関数を呼び出すと vl.foo: Element が利用可能になります。

この関数によって定義されるプロパティは、列挙可能かつ変更可能かつ削除可能です。

この関数によって関連付けられた Element は関連する ProtoViewLogic に対してイベントを post() します。この関数内で post() を呼び出すイベントリスナーが Element に登録されます。

どのイベントの通知を有効あるいは無効にするかは、カスタムデータ属性 data-active-events にカンマ区切りのイベント種別のリストを設定するか、addActiveEvents() および removeActiveEvents() によって指定されます。

ProtoViewLogic がプロパティとして持つ Element には所有権があります。所有権は relateElements()ElementProtoViewLogic に関連付けられる際に設定されます。

異なる ProtoViewLogic が所有する ElementrelateElements() の引数として渡された場合、 disrelateElements() を呼び出して元の所有権を解消します。その後、対象の ProtoViewLogic を所有者とする所有権をその Element に対して設定します。

所有権の移動によってイベントの通知先も新しい所有者へ変更されます。

この関数によって関連付けられた Element は、reflectValues() によって data-primary 属性値に対応する名前のプロパティまたは value プロパティが更新されます。また curateValues() によってそれらのプロパティの値が参照されるようになります。

これらの関数 reflectValues() および curateValues() は、対象の ProtoViewLogic へのデータバインディングに利用されます。

もし対象の ProtoViewLogic がいずれかの ObservableObject に対して ObservableObject::bindData() で結合されている場合、結合先のバインディングソースとなる ObservableObject やその ObservableObject に結合している他のバインディングターゲットに対する変更は、対象の ProtoViewLogic 自身と関連付けられた Element に反映されます。

data-primary 属性に関する注意点として、data-primary 属性の値がドット "." を含む場合、ドットの直後の語は、ドットの直前の語のプロパティ名で指定される、下位のオブジェクトのプロパティ名を表します。

例えば <span data-primary="foo.bar"></span> を表す e というオブジェクトがあるとして、そのオブジェクトは e.foo という下位のオブジェクトを持ち、それは e.foo.bar というプロパティを持つことが期待されます。

メッセージ

info

メッセージの概要についてはメッセージパッシングを、他のメッセージについては ViewLogic の状態変更を通知するメッセージを参照してください。

この関数の呼び出し後、対象の ProtoViewLogic に対してそれ自身から、プロパティ id として "vl$propertiesModified" を値に持つメッセージが送られます。このメッセージが持つオブジェクトは以下の通りです:

  • id: "vl$propertiesModified"
  • code: null
  • param: { addedProperties, removedProperties }
    • addedProperties: ({ [property_name: string]: Element | Array<Element> })? --- 新たにプロパティとして追加された要素です。
    • removedProperties: ({ [property_name: string]: Element | Array<Element> })? --- プロパティから取り除かれた要素です。
  • origin: ProtoViewLogic
  • target: ProtoViewLogic