View
モジュール一覧
概要
Alierフレームワークにおいて、アプリケーションはModelとViewの2つの層で構成されます。 このうち、Viewの層はアプリケーションの状態(データ)および状態変更(イベント)の提示する役割と、ユーザがアプリケーションを操作するためのインターフェース(ユーザインターフェース; UI)を提供し、ユーザ操作の結果をModelへ伝達する役割とを持ちます。
View層を構成する部品として、Alierフレームワークでは、ViewLogic モジュールから ViewLogic クラス を提供しています。ViewLogic クラスのインスタンスは、以下の2つのことを行います:
-
ユーザからの操作とアプリケーションの状態変更を、メッセージという形で統一的に扱います。 メッセージに駆動され、必要に応じて、
ViewLogicのインスタンスはModel層からデータを取得したりModel層へユーザ入力を与えたりします。 -
アプリケーションの画面に表示される内容と画面上のUIを提供します。
コンテナ
Alierフレームワークでは、アプリケーションの画面に表示されるひとまとまりの内容とUIを総称して、コンテナ (container) と呼んでいます。「ひとまとまり」の意味するところは、アプリケーション全体の画面とUIは、複数のコンテナの組み合わせによって構成されるということです。
コンテナは、HTML形式のファイルかテキストを使って定義されます。
ファイルから定義する場合、ViewLogic.loadContainer() かその同期関数版の ViewLogic.loadContainerSync() に引数 { file } としてHTMLファイルのパスを与えます。
// ViewLogic クラスをインポートします
import { ViewLogic } from "/alier_sys/ViewLogic.js";
// ViewLogic の派生クラスを定義します
class LoadContainerExample extends ViewLogic {
// コンストラクタから loadContainer() を呼び出し、
// "LoadContainerExample.html" に定義されたコンテナを読み込みます。
constructor() {
super();
// LoadContainerExample.html を読み込み、コンテナを取得します。
// このHTMLファイルは必ずカスタム要素 <alier-container> を含んでいなければなりません。
// <alier-container> はコンテナの構成要素をまとめるルート要素として使われます。
const container = this.loadContainer({ file: "LoadContainerExample.html" });
// コンテナから UI を構成する要素を取得します
const uiElements = this.collectElements(container);
// UI の構成要素をこの ViewLogic インスタンスに関連付けます
this.relateElements(uiElements);
}
}
// LoadContainerExample のインスタンスを生成します
const loadContainerExample = new LoadContainerExample();
上記の例では ViewLogic.loadContainer() の他に ProtoViewLogic.collectElements(), ProtoViewLogic.relateElements() を使いました。
これらはそれぞれ、コンテナの中にあるUIの構成要素(UI要素)を収集し、ViewLogic インスタンスのプロパティとしてアクセスできるようにしています。
また relateElements() を行うことで、コンテナ内のUI要素の操作が、対象の ViewLogic インスタンスへのメッセージとして伝わるようになります。
テキストから定義する場合は代わりに、引数 { text } としてHTML文字列を与えます。
// ViewLogic クラスをインポートします
import { ViewLogic } from "/alier_sys/ViewLogic.js";
// HTMLテキストを用意します
const LOAD_CONTAINER_EXAMPLE_HTML = `<html>
<head></head>
<body><alier-container>
<!-- ここにコンテナを構成する要素を記述します -->
</alier-container></body>
</html>`;
// ViewLogic の派生クラスを定義します
class LoadContainerExample extends ViewLogic {
// コンストラクタから loadContainer() を呼び出し、
// "MyViewLogic.html" に定義されたコンテナを読み込みます。
constructor() {
super();
// テキスト MY_VIEW_LOGIC_HTML を読み込み、コンテナを取得します
const container = this.loadContainer({ text: LOAD_CONTAINER_EXAMPLE_HTML });
// コンテナから UI を構成する要素を取得します
const uiElements = this.collectElements(container);
// UI の構成要素をこの ViewLogic インスタンスに関連付けます
this.relateElements(uiElements);
}
}
// LoadContainerExample のインスタンスを生成します
const loadContainerExample = new LoadContainerExample();
上記の例では、HTML文字列 LOAD_CONTAINER_EXAMPLE_HTML の中に <alier-container> というカスタム要素を定義しています。
このカスタム要素は、ViewLogic.loadContainer() の引数として与えられたHTML文字列の中から、コンテナを構築する要素の目印に使われます。
<alier-container> の探索は、引数の種類によらず loadContainer() および loadContainerSync() の中で行われます。つまり、引数 { file } としてHTMLファイルパスを渡す前述の例においても、参照されるHTMLファイルの中にはカスタム要素 <alier-container> が記述されている必要があります。
メッセージの制御
ViewLogic を使ってUI要素の操作などのイベントの制御をするには、コールバック関数 ProtoViewLogic.messageHandler() を実装します。
messageHandler() の引数として、メッセージの種別を表すプロパティ id および code の設定されたオブジェクトが与えられるため、それらの識別子に従って処理を振り分けます。
メッセージオブジェクトの id プロパティを使った処理の振り分けには、メッセージオブジェクトに設定された deliver() メソッドを使います。
// NOTE: ViewLogic の import は省略しています
// メッセージ制御を実装する ViewLogic の派生クラスを定義します
class MessageHandlingExample extends ViewLogic {
// NOTE: constructor() の実装は省略しています
// messageHandler() をオーバーライドします。
async messageHandler(message) {
// deliver() メソッドを呼び出し、message.id によって処理を振り分けます。
message.deliver({
clearButton: () => { /* 消去ボタンの操作が行われた際に実行されます */ },
submitButton: () => { /* 投稿ボタンの操作が行われた際に実行されます */ },
editArea: () => { /* 編集領域の操作が行われた際に実行されます */ }
});
}
}
メッセージオブジェクトの id プロパティの値は、ProtoViewLogic.relateElements() によって関連付けられたUI要素の名前が使われます。
例えば clearButton というプロパティ名で上記の MessageHandlingExample のインスタンスにUI要素が設定されている場合、そのUI要素に対するユーザ操作に起因して、deliver() の引数の同名のプロパティに設定された関数が呼び出されます。
補足
ViewLogic の状態変更を通知するメッセージ
ViewLogic のインスタンスの状態が変更される際、変更を通知するメッセージがそのインスタンスに対して送られます。
状態変更を通知するメッセージは id が "vl$" で始まるメッセージです。メッセージの発生源 origin および送り先 target にはそれぞれ、状態変更が起こった ViewLogic のインスタンス自身が設定されます。
状態変更の通知は、ViewLogic のインスタンスの状態を変える、特定のメソッドの呼び出しに際し行われます。
それぞれの種別の状態変更がどのメソッドの呼び出しに対して起こるかについては、下記の項目を参照してください。
親子関係の変更
ViewLogic(または ProtoViewLogic)のインスタンスの親(parent プロパティ)が変わった際、以下の id のメッセージが送られます。
-
id:"vl$connectionChanged" -
状態変更の契機:
以下のメソッドの呼び出しに際し、状態変更の起こった
ViewLogicに対してメッセージが送られます。
プロパティの変更
ViewLogic(または ProtoViewLogic)のインスタンスのプロパティとして Element や ViewLogic のインスタンスが追加されたか、またはそれらを値に持つプロパティが変更または削除された際、以下の id のメッセージが送られます。
-
id:"vl$propertiesModified" -
状態変更の契機:
以下のメソッドの呼び出しに際し、状態変更の起こった
ViewLogicに対してメッセージが送られます。
コンテナの変更
ViewLogic のインスタンスのコンテナ(container プロパティ)が変更された際、以下の id のメッセージが送られます。
-
id:"vl$containerUpdated" -
状態変更の契機:
以下のメソッドの呼び出しに際し、状態変更の起こった
ViewLogicに対してメッセージが送られます。
AlierView への取り付け
ViewLogic のインスタンスが AlierView のインスタンスに取り付けられた(ViewLogic インスタンスのプロパティ host に AlierView のインスタンスが設定された)際、以下の id のメッセージが送られます。
-
id:"vl$attached" -
状態変更の契機:
以下のメソッドの呼び出しに際し、状態変更の起こった
ViewLogicに対してメッセージが送られます。
AlierView からの取り外し
ViewLogic のインスタンスが AlierView のインスタンスから取り外された(ViewLogic インスタンスのプロパティ host に null が設定された)際、以下の id のメッセージが送られます。
-
id:"vl$detached" -
状態変更の契機:
以下のメソッドの呼び出しに際し、状態変更の起こった
ViewLogicに対してメッセージが送られます。
- 既に別の
ViewLogicが取り付けられているAlierViewに対して、別のViewLogicを取り付ける(ViewLogic.attachTo()またはAlierView.attach()を呼び出す)と、既存のViewLogicは取り外されます。