概要
ぼんやりとしか把握していないTypeScriptが色々とバージョンアップしたらしいのでMithrilのチュートリアルをTypeScriptで写経して学びます。タイトルそのまんまです。
[追記]
こちらでコンパイルエラーを修正してみました。
環境
- TypeScript 1.6.2
- Mithril 0.2.0
root
├ server.js
├ client
│ ├ app.js <-app.tsをコンパイルしたファイル
│ ├ mithril.min.js
│ └ index.html
├ client-src
│ └ app.ts
└ typings
└mithril
└mithril.d.ts
まずは下準備
チュートリアルを参考にindex.htmlを用意。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ToDoアプリケーション</title>
<script src="mithril.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
後は適当なWebサーバーを起動しておきます。とりあえずnodeで用意しました。
server.js
var express = require("express");
var app = express();
app.use(express.static("client"));
console.log("start listening at 3773");
app.listen(3773);
写経したものがこちら
以下の通りに書いてみました。可能な限り型を明示したつもりです。しかし、最後のm.mountするところでTS2345エラーが発生しているので調査中。エラー出てるくせにapp.jsが生成されて、アプリケーション自体は実行できているのが謎ですが…。
app.ts
/// <reference path="../typings/mithril/mithril.d.ts" />
import MithrilProperty = _mithril.MithrilProperty;
/**
* Model
*/
class Todo {
description: MithrilProperty<string>;
done: MithrilProperty<boolean>;
constructor(description:string) {
this.description = m.prop<string>(description);
this.done = m.prop<boolean>(false);
}
}
//ビュー・モデルは表示されているTodoのリストを管理し、
//作成が完了する前のTodoの説明を格納したり、
//作成が可能かどうかを判定するロジックや、
//Todoが追加された後にテキスト入力をクリアする責務を持つ
namespace todoVM {
//新しいTodoを作成する前の、入力中のTodoの名前を保持するスロット
export var description: MithrilProperty<string>;
//アクティブなTodoのリスト
export var todoList: MithrilProperty<Todo[]>;
//export var done: MithrilProperty<boolean>;
/**
* 初期化
*/
export function init () {
todoVM.todoList = m.prop<Todo[]>([]);
todoVM.description = m.prop<string>("");
//todoVM.done = m.prop<boolean>(false);
}
/**
* Todoの追加をしてdescriptionをクリア
*/
export function add () {
if (description()) {
todoVM.todoList().push(new Todo(description()));
todoVM.description("");
}
}
}
/**
* Controller
* コントローラは、モデルの中のどの部分が、現在のページと関連するのかを定義している
* この場合は1つのビュー・モデルですべてを取り仕切っている
*/
function controller() {
todoVM.init();
}
/**
* View
* @returns {any}
*/
var view = () => {
return m("html", [
m("body", [
m("input", {onchange: m.withAttr("value", todoVM.description), value: todoVM.description()}),
m("button", {onclick: todoVM.add}, "追加"),
m("table", [
todoVM.todoList().map((task: Todo, index: number) => {
return m("tr", [
m("td", [
m("input[type=checkbox]", {onclick: m.withAttr("checked", task.done), checked: task.done()})
]),
m("td", {style: {textDecoration: task.done() ? "line-through" : "none"}}, task.description()),
])
})
])
])
]);
};
window.onload = () => {
m.mount(document.getElementById("root"), {controller: controller, view: view});
};
まだまだ理解の甘いところだらけ。変換後のapp.js、TypeScript、Mithrilのドキュメントと照らしあわせて勉強中。