🎃

宣言的なJSフレームワーク デモ解説(1)

2022/05/10に公開約4,700字

概要

KnockoutにあるchooseTicketの例をdata-x.jsで作るとどうなるかを解説する。

フレームワーク

https://github.com/mogera551/data-x.js

デモ概要

チケットの種類を選択すると、価格を含むメッセージを表示する。
クリアボタンを押すと、選択しているチケットをクリアする。

ソース解説

index.html

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index.html

フレームワークの読み込み

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index.html#L3-L3

mainという名前のブロックをロードする。バインドルールを外部ファイルで持つ。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index.html#L5-L5

フレームワークの実行。scriptタグのtype属性にmoduleを指定。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index.html#L7-L10

index-spa/css、index-spa/html、index-spa/module

ブロックを入れるフォルダ。ブロックはcss、html、JSモジュールで構成される。ファイル名は、ブロック名+拡張子(.css, .html, js)。

main.html

mainブロックのhtml。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/html/main.html

selectタグのname属性の値("ticketId|number-value")は、viewModelのticketIdプロパティとバインドし、number-valueフィルターを適用する。number-valueフィルターは、viewModelのプロパティ値を数値型として扱う。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/html/main.html#L2-L2

配列データの繰り返しは、繰り返す要素をtemplateタグで囲む

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/html/main.html#L4-L6

buttonタグは、暗黙的にviwModelのclickイベントハンドラを実行する。clickイベントハンドラ名は、event+イベント名+buttonのname属性。ここでは、eventClickClearとなる。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/html/main.html#L8-L8

main.js

mainブロックのjsモジュール。ViewModelのクラス定義、プロパティ依存関係ルールの定義とそれらのエクスポートを行う。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/module/main.js

チケットの配列データ。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/module/main.js#L1-L5

ViewModelのクラス定義。AppViewModelという名前でクラスを作成する。
データプロパティは、"@"もしくは"@@"+プロパティ名で定義する。
"@"はリードオンリー、"@@"は書き込み可(双方向バインド)を示す。
プロパティ名のあとに"#"を続けて、get/set/initの関数を定義することができる。
イベントハンドラは、"#"+イベントハンドラ名で定義する。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/module/main.js#L7-L18

optionタグとバインドするプロパティ。繰り返す要素は、アスタリスクを含むドット記法で記述する。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/module/main.js#L8-L10

selectタグのvalueとバインドするプロパティ。選択したチケットIDを保存する。書き込む必要があるので"@@"とする。バインド時number-valueフィルタを使っているので、ticketIdは数値型として扱われる。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/module/main.js#L12-L12

選択したチケットの情報。findで選択したチケットIDに一致するものを探す。ticketIdは数値型なので、===で評価できる。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/module/main.js#L13-L15

イベントハンドラ、クリアボタンを押したときの動作。選択したチケットをクリアする。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/module/main.js#L17-L17

プロパティ間の依存関係ルール。
[ "ticket", [ "ticketId" ] ],
の意味は、ticketIdプロパティが更新されたら、ticketの値をバインドしているhtml要素の属性へ反映する。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/module/main.js#L20-L24

デフォルトエキスポートを行う。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/module/main.js#L26-L26

main.bind.css

mainブロックのバインドルール。
CSSと同じような感じで使う。対象のhtml要素をセレクタで指定し、バインドルールを定義していく。
バインドルールは、
--bind-html要素のプロパティ: viewModelのプロパティ
フィルターをつける場合、viewModelプロパティの後に、|でフィルター名を続ける。
html要素のプロパティが、階層を持つ場合、-で区切る

--bind-style-display: ticket|style-display;

リストなどのように要素を繰り返す場合、templateに--loop: リストのプロパティを指定する。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/css/main.bind.css#L1-L25

繰り返すリストの設定。--loopとし、繰り返すリストのプロパティ名を指定する。ここでは、viewModelのticketsプロパティ。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/css/main.bind.css#L1-L3

繰り返す要素の設定。optionのvalue属性とviewModelのプロパティ"tcikets.*.id"、optionのtextContent属性とviewModelのプロパティ"tcikets.*.name"をバインドする。アスタリスクを含むドット記法でそのまま指定する。templateタグをまたいだセレクタは指定できないことに注意する。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/css/main.bind.css#L5-L8

クリアボタンのdisabled属性とviewModelのプロパティticketをバインド。falseyフィルターはviewModelの値がfalseyな場合、trueとなる。チケットを選択した場合、クリアボタンが有効となる。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/css/main.bind.css#L10-L12

メッセージを表示する領域のstyle.display属性とviewModelのプロパティticketをバインド。style-displayフィルターは、viewModelの値が真の場合""、偽の場合"none"を返す。チケットを選択した場合、メッセージを表示する。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/css/main.bind.css#L14-L16

メッセージに表示する名前と価格をそれぞれviewModelのプロパティticket.nameとプロパティticket.priceとバインドする。

https://github.com/mogera551/data-x.js/blob/v0.2.2/demo/chooseTicket/index-spa/css/main.bind.css#L18-L24

感想

knockoutよりも長くなった。
繰り返す部分を変数など使わず*を用いて宣言的に定義できたので満足。

Discussion

ログインするとコメントできます