サンプルコードの説明
今回のサンプルコードの処理を図を使って説明すると、次のようになります。
- 「m.mount」実行後、Controllerの処理が実行されます。
- Controllerで各Modelからデータを取得し、thisに格納します。
- Viewの第1引数にcontrollerが入っているので、必要なデータを抽出しレンダリング内容を定義します。
- Controller処理完了後、初回のレンダリング処理が行われます。
- レンダリングされたHTMLでイベントをキャッチすると、Controllerで定義しているメソッドを実行します。
- ControllerのメソッドからModelのメソッドを実行し、データの変更を行います。
- イベント実行のタイミングで、再度レンダリング処理が行われます。
Mithrilの主要メソッドの説明
m.mount
Mithrilで定義したアプリケーションを実行します。controllerの実行とViewの初回レンダリングを行うメソッドです。
m.mount(document.getElementById("root"), {
controller: myCtrl,
view: myView
});
| 引数 | 名前 | 説明 |
|---|---|---|
| 第1引数 | root | レンダリング対象のDomを指定 |
| 第2引数 | module | controllerとviewを定義 |
「m.mount」を実行すると、まずデータの監視処理が開始され、controller Classがインスタンス化されます。Controllerの処理完了後、データの監視処理が停止。viewのレンダリング通知が実行されます。
viewで生成されたDOMは「root」で設定した要素内に展開されます。
v0.1.34までは「m.module」という名称でしたが、v0.2.0から「m.mount」に変更されました。ただし、互換性は確保されているので、v0.2.0でも引き続き「m.module」で実行することは可能です。
m
VirtualDOMの生成に使用する関数です。基本はView側で定義します。
Reactの「React.createElement」と同等の動作をします。CSSセレクタの形式でも定義できるのが特徴と言えます。
m("br") //<br>
m("div", "Hello") //<div>Hello</div>
m("div", {class: "container"}, "Hello"); //<div class="container">Hello</div>
m("div.container", "Hello"); //<div class="container">Hello</div>
m("div[href='hoge.html']", "Hello"); //<div href="hoge.html">Hello</div>
- 第1引数にCSSセレクタを定義することで、要素が作成されます。
- 第2引数に設定する属性と値をobject形式で指定できます。省略も可能です。
- 第3引数に要素の値を入力します。
JSXのようにDOM形式でViewを書ける、MSXというコンパイラも用意されています。MSXを使いDOM形式でViewを定義するのが現在主流になっていますが、今回は内部の挙動を分かりやすく見るために、上記の形式で記載させていただいています。MSXについての詳細は次回お話します。
m.withAttr
「onclick」や「onchange」などのイベント発生時に実行する関数を定義する際に使用します。DOMのイベントハンドラに設定する形式で使用します。
var myCtrl = function(ctrl) {
var that = this;
this.text = m.prop("first");
this.onChangeText = function(v){
that.text = m.prop(v);
};
}
var myView = function(ctrl){
return [
m("p", ctrl.text() ),
m("button", { onclick: m.withAttr("value", ctrl.onChangeText), value:"change" }, "change value"),
];
};
| 引数 | 名前 | 説明 |
|---|---|---|
| 第1引数 | prop | withAttrCallbackの第1引数として渡す、属性名を指定。 |
| 第2引数 | withAttrCallback | callback関数を指定。第1引数にpropで指定した属性の値が入る。 |
m.prop
viewModel処理を簡易的に設定できるように用意された、getter/setterメソッドです。基本はcontrolleやmodelで使用します。
var myCtrl = function() {
//set value
this.name = m.prop("hoge");
//this.nameが関数に変更されます
console.log(this.name); // -> function(){...}
//get value
console.log(this.name()); // -> "hoge"
//change value
this.name("fuga");
//get value
console.log(this.name()); // -> "fuga"
};
「m.withAttr」と連携することで、簡潔に処理を書くことができます。
var myCtrl = function(ctrl) {
this.inputData = m.prop("")
}
var myView = function(ctrl) {
return [
m("input", {onchange: m.withAttr("value", ctrl.inputData) }),
m("p", ctrl.inputData())
];
}
m.request
mithrilで通信処理を行うためのメソッドです。内部的にレンダリング監視処理が実行されるため、xhr通信を行う際は必須です。また、内部でm.propが使われています。
var myCtrl = function(){
//簡易的な利用方法
var data = m.request({method: "GET", url: "data.json"});
//success,error検知
var data2 = [];
m.request({
method: "GET",
url: "data.json"
}).then(
//success
function(resp) {
data2 = resp;
alert("success");
},
//error
function(resp) {
alert("error");
}
);
//パース処理後格納する場合
var data3 = m.request({method: "GET", url: "data.json"})
.then(function(resp){
return resp.filter(function(v){ return v.id === 2; });
});
//確認
this.onClick = function(){
console.log(data()); //-> [{id: 1, name: "John"}, {id: 2, name: "Mary"}]
console.log(data2); //-> [{id: 1, name: "John"}, {id: 2, name: "Mary"}]
console.log(data3()); //-> [{id: 2, name: "Mary"}]
};
};

