ProtoViewLogic: disrelateViewLogics()

与えられた ProtoViewLogic を子とする親子関係を解消します。

構文

protoViewLogic.disrelateViewLogics() => object
protoViewLogic.disrelateViewLogics(relatedViewLogic) => object
protoViewLogic.disrelateViewLogics(relatedViewLogicName) => object

引数

  • relatedViewLogicOrItsName: ProtoViewLogic | ProtoViewLogic[] | string | null

    対象の ProtoViewLogic の子として登録済みの ProtoViewLogic または ProtoViewLogic[] か、それらを参照するプロパティ名か、または null です。配列の場合は relateViewLogics() で登録した配列と対応しています。null の場合、すべての子の ProtoViewLogic の親子関係を解消します。

返値: object

親子関係の解消された ProtoViewLogic とその旧名を対応づけるオブジェクトです。

例外

  • TypeError
    • 引数 relatedViewLogicOrItsName が、string でも配列でも ProtoViewLogic でもなかった場合。
    • 引数 relatedViewLogicOrItsName の配列成分が、ProtoViewLogic でなかった場合。
  • ReferenceError
    • 引数 relatedViewLogicOrItsName に指定された文字列が、対象の ProtoViewLogic のプロパティに存在しなかった場合。
    • 引数 relatedViewLogicOrItsname に指定された ProtoViewLogic が、対象の ProtoViewLogic の子でなかった場合。
    • 引数 relatedViewLogicOrItsName の配列成分が、対象の ProtoViewLogic に配列として関連付けられてなかった場合。
    • 引数 relatedViewLogicOrItsName の配列成分に、異なる name を持つ ProtoViewLogic が存在した場合。

const { ProtoViewLogic } = await Alier.import("/alier_sys/ProtoViewLogic.js");

console.group("Example of ProtoViewLogic.disrelateViewLogics()");

const Watcher = class extends ProtoViewLogic {
    async messageHandler(msg) {
        console.groupCollapsed(`${msg.id}+${msg.code}`);

        console.log("%cmsg.id                      :", "font-weight: bold; font-family: monospace;", msg.id);
        console.log("%cmsg.code                    :", "font-weight: bold; font-family: monospace;", msg.code);
        console.log("%cmsg.origin                  :", "font-weight: bold; font-family: monospace;", msg.origin);
        console.log("%cmsg.target                  :", "font-weight: bold; font-family: monospace;", msg.target);
        console.log("%cmsg.param                   :", "font-weight: bold; font-family: monospace;", msg.param);
        console.log("%cmsg.param?.state            :", "font-weight: bold; font-family: monospace;", msg.param?.state);
        console.log("%cmsg.param?.newName          :", "font-weight: bold; font-family: monospace;", msg.param?.newName);
        console.log("%cmsg.param?.newParent        :", "font-weight: bold; font-family: monospace;", msg.param?.newParent);
        console.log("%cmsg.param?.oldName          :", "font-weight: bold; font-family: monospace;", msg.param?.oldName);
        console.log("%cmsg.param?.oldParent        :", "font-weight: bold; font-family: monospace;", msg.param?.oldParent);
        console.log("%cmsg.param?.addedProperties  :", "font-weight: bold; font-family: monospace;", msg.param?.addedProperties);
        console.log("%cmsg.param?.removedProperties:", "font-weight: bold; font-family: monospace;", msg.param?.removedProperties);

        console.groupEnd();
    }
};

const vl  = new Watcher;
const foo = new Watcher;
const bar = new Watcher;
const baz = [
    new Watcher,
    new Watcher,
    new Watcher
];

console.log("eval: vl.relateViewLogics({ foo, bar, baz })");
vl.relateViewLogics({ foo, bar, baz });
// ==>  msg.param.state: connected; msg.param.oldName: null; msg.param.newName: foo
// ==>  msg.param.state: connected; msg.param.oldName: null; msg.param.newName: bar
// ==>  msg.param.state: connected; msg.param.oldName: null; msg.param.newName: baz

console.log(`(vl.foo === foo) ==> ${vl.foo === foo}`);
// ==>  true
console.log(`(vl.bar === bar) ==> ${vl.bar === bar}`);
// ==>  true
console.log(`(vl.baz != null && vl.baz.every((v, i) => (v === baz[i]))) ==> ${vl.baz != null && vl.baz.every((v, i) => (v === baz[i]))}`);
// ==>  true

//  (1)  インスタンスを指定して foo と vl の親子関係を解消する
console.log("eval: vl.disrelateViewLogics(foo)");
console.log("==> ", vl.disrelateViewLogics(foo));
// ==>  { foo }

console.log(`(vl.foo === foo) ==> ${vl.foo === foo}`);
// ==> false; foo は disrelateViewLogics() されたため、 vl.foo は削除されている

//  (2)  名前を指定して bar と vl の親子関係を解消する
console.log("eval: vl.disrelateViewLogics(\"bar\")");
console.log("==> ", vl.disrelateViewLogics("bar"));
// ==>  { bar }

console.log(`(vl.bar === bar) ==> ${vl.bar === bar}`);
// ==> false; bar は disrelateViewLogics() されたため、 vl.bar は削除されている

//  (3)-1  配列を指定して baz の配列成分と vl の親子関係を解消する
console.log("eval: vl.disrelateViewLogics([baz[0], baz[2]])");
console.log("==> ", vl.disrelateViewLogics([baz[0], baz[2]]));
// ==>  { baz: [ baz[0], <empty slot>, baz[2] ] }

console.log(`(vl.baz != null && vl.baz.every((v, i) => (v === baz[i]))) ==> ${vl.baz != null && vl.baz.every((v, i) => (v === baz[i]))}`);
// ==>  true; baz の配列成分は disrelateViewLogics() されたが、一部が残っているため、 vl.baz はまだ存在する

//  (3)-2  配列を指定して baz の残りの配列成分と vl の親子関係を解消する
console.log("eval: vl.disrelateViewLogics([baz[1]])");
console.log("==> ", vl.disrelateViewLogics([baz[1]]));
// ==>  { baz: [ <empty slot>, baz[1], <empty slot> ] }

console.log(`(vl.baz != null && vl.baz.every((v, i) => (v === baz[i]))) ==> ${vl.baz != null && vl.baz.every((v, i) => (v === baz[i]))}`);
// ==> false; baz のすべての配列成分が disrelateViewLogics() されたため、 vl.baz は削除されている

console.log("eval: vl.relateViewLogics({ foo, bar, baz })");
vl.relateViewLogics({ foo, bar, baz });

//  (4)  引数なしで呼び出してすべての子との親子関係を解消する
console.log("eval: vl.disrelateViewLogics()");
console.log("==> ", vl.disrelateViewLogics());
// ==>  { foo, bar, baz: [ baz[0], baz[1], baz[2] ] }

console.groupEnd();

解説

対象の ProtoViewLogic から、引数 relatedViewLogicOrItsName で指定された子の ProtoViewLogic への参照を取り除きます。

取り除かれた ProtoViewLogicparent プロパティおよび name プロパティはそれぞれ null に変更されます。

返値のプロパティ名には、取り除いた ProtoViewLogic に設定されていた name が設定されます。

メッセージ

info

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

vl$connectionChanged

disrelateViewLogics() によって子の ProtoViewLogicparent プロパティが変更されると、子にメッセージ { id: "vl$connectionChanged" } が送信されます。

  • id: "vl$connectionChanged"
  • code: null
  • param: { state, oldParent, oldName, newParent, newName }
    • state: "disconnected" --- 他の ProtoViewLogic の子でなくなったことを表しています。
    • oldParent: ViewLlogic --- 直前まで設定されていた parent プロパティの値です。
    • oldName: string --- 直前まで設定されていた name プロパティの値です。
    • newParent: null --- 新たに設定された parent プロパティの値です。disrelateViewLogics() では常に null になります。
    • newName: null --- 新たに設定された name プロパティの値です。disrelateViewLogics() では常に null になります。
  • origin: ProtoViewLogic
  • target: ProtoViewLogic
const parent = new ProtoViewLogic;
const child = new class extends ProtoViewLogic {
    async messageHandler(msg) {
        if (msg.id === "vl$connectionChanged") {
            if (msg.param.state === "disconnected") {
                console.log(`old name: ${msg.param.oldName}`);
            }
        }
    }
};
parent.relateViewLogics({ foo: child });
parent.disrelateViewLogics(child);
// => 以下がログ出力されます:
//    old name: foo

メッセージ { id: "vl$connectionChanged" }relateViewLogics() でも送出されます。

vl$propertiesModified

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

  • id: "vl$propertiesModified"
  • code: null
  • param: { addedProperties, removedProperties }
    • addedProperties: ({ [property_name: string]: ProtoViewLogic | ProtoViewLogic[] })? --- 新たにプロパティに追加された ProtoViewLogic です。disrelateViewLogics() の呼び出しでは常に null になります。
    • removedProperties: ({ [property_name: string]: ProtoViewLogic | ProtoViewLogic[] })? --- プロパティから取り除かれた ProtoViewLogic です。
  • origin: ProtoViewLogic
  • target: ProtoViewLogic
const parent = new class extends ProtoViewLogic {
    async messageHandler(msg) {
        if (msg.id === "vl$propertiesModified") {
            if (msg.param.removedProperties != null) {
                const removedKeys = Object.keys(msg.param.removedProperties)
                console.log(`removed properties: ${JSON.stringify(removedKeys)}`);
            }
        }
    }
};
const child = new ProtoViewLogic;
parent.relateViewLogics({ bar: child });
parent.disrelateViewLogics(child);
// => 以下がログ出力されます:
//    removed properties: ["bar"]

メッセージ { id: "vl$propertiedModified" }relateViewLogics でも送出されます。