という訳でTypeScriptでReactiveなコード書いてみました。
細かい実装は下記を見ていただければと
https://github.com/ts020/reactive_template
詳しくは、readme.htmlをご覧ください。
ちなみに、仮想DOMは実装しんどかったので今回は見送りました。
下記を重視して作ってみました
. Modelの値が変更されたときにviewに通知される事
. 通知にあわせて、自動的に再描画される事
. 値が変更されているプロパティに関係する対象だけが再描画される事
. Canvasやwebglでも使える事
MVCです
Controller
///<reference path="Model.ts" />
///<reference path="View.ts" />
module app {
export class Controller {
view:View;
model:Model;
constructor(initialData:any=null) {
this.model = new Model(initialData);
this.view = new View(this.model);
}
showName(label:string):void {
this.model.setName(label);
}
}
}
Model
setPropertyを実行すると、値に変更が有った場合に[change]イベントが16ミリ秒後実行されます。
遅延実行している理由は、描画とロジック処理負荷を分けるためデス。
また、[change]イベント送出までは、プロパティをどれだけいじっても変更通知される事はないです。
///<reference path="olib/reactive/ModelBase.ts" />
module app {
export class Model extends olib.reactive.ModelBase {
protected init(initialData:any = null):void {
this.name = initialData ? initialData.name || "" : "";
}
setName(label:string):void {
this.name = label;
}
set name(value:string) {
this.setProperty("name",value);
}
get name():string {
return this.getProperty("name");
}
}
}
View
model値が変更されるとview.updateが実行されます。
updateの中に描画処理をまとめる事で描画負荷のコントロールを行いやすくします。
bindでプロパティに変更が有るときだけ処理が実行されます。
差分のみの変更をするとこで描画負荷を下げます。
///<reference path="olib/reactive/ViewBase.ts" />
///<reference path="Model.ts" />
module app {
export class View extends olib.reactive.ViewBase<Model> {
nameLabel:HTMLElement;
protected init():void {
this.nameLabel = <HTMLElement>document.querySelector("#nameLabel");
this.update();
}
update():void {
this.bind("name", (value)=>{
this.nameLabel.innerHTML = value;
});
}
}
}
HTML
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:700,300' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="resource/style.css">
</head>
<body>
<h1>SPA REACTIVE MVC TEMPLATE</h1>
<div id="nameLabel"></div>
<input type="text" id="nameInput" onkeyup="controller.showName(this.value)" />
</div>
</body>
<script type="text/javascript" src="resource/App.js"></script>
<script type="text/javascript">
var controller = new app.Controller({
name : "Hello World"
});
</script>
</html>
こんな感じです。
テキストを入力すると、文字がかわります
