makeElementObserver

モジュールパス: /alier_sys/makeElementObserver.js

標準のエレメントを ObservableValue とバインドし、プライマリプロパティを監視できるようにするためのユーティリティ関数です。

この関数によって以下のメソッドとプロパティが割り当てられます。

  • onDataBinding(): ObservableValue.bindData() でバインドした時に呼び出されるコールバック関数
  • setValue(): プライマリプロパティに値を設定する
  • getValue(): プライマリプロパティの値を取得する
  • source: バインディングソースオブジェクト

また、プライマリプロパティに値を代入した際、バインディングソースにプライマリプロパティの値を伝播させます。 プライマリプロパティは data-primary 属性で指定したプロパティまたは value プロパティです。

構文

makeElementObserver(element) => HTMLElement

引数

  • element: HTMLElement

    バインド対象となる要素です。

返値: HTMLElement

ObservableValue とバインド可能な要素です。

引数で与えた element と同じオブジェクトです。

例外

  • TypeError
    • 引数 elementHTMLElement のインスタンスではなかった場合。

入力要素 <input> をこの関数でバインド可能にし、ObservableValue とバインドします。

import makeElementObserver from "/alier_sys/makeElementObserver.js";
import { ObservableValue } from "/alier_sys/ObservableValue.js";

const input = document.createElement("input");

makeElementObserver(input);

// 双方向バインド
const ov = new ObservableValue("foo", true);
ov.bindData(input);

バインド時にはバインドソースの値がバインドターゲットに反映されるので、 input のプライマリプロパティ value の値に "foo" が設定されます。

console.log(input.value);
// => "foo"

ov の値を ObservableValue.setValue で更新すると、ターゲットである input にもその値が反映されます。

ov.setValue("bar");
console.log(input.value);
// => "bar"

この ovinput は双方向モードでバインドされているので、input のプライマリプロパティ value を更新すると、その値が ov にも反映されます。

input.value = "foobar";
console.log(ov.getValue());
// => "foobar"

ユーザーの入力などの結果を ObservableValue と同期するためには、別途イベントリスナーを設定する必要があります。

input.addEventListener("input", () => {
    input.source?.setValue(input.value);
});

// ブラウザ上でユーザーが "baz" と入力

console.log(ov.getValue());
// => "baz"

プライマリプロパティの変更

プライマリプロパティを value 以外のプロパティにしたい時は、そのプロパティの名前を data-primary 属性に指定します。

次のサンプルコードでは、コンテンツ区間要素 <span> のプライマリプロパティに innerText を指定しています。

const span = document.createElement("span");

// プライマリプロパティを指定
span.setAttribute("data-primary", "innerText");

makeElementObserver(span);

const ov = new ObservableValue("foo");
ov.bindData(span);

console.log(span.innerText);
// => "foo"

ov.setValue("bar");
console.log(span.innerText);
// => "bar"