knockoutjsとhaxeを組み合わせて小規模なSPAを作成してみるサンプルです。
knockoutjsをHaxeで利用するためのexternクラス
pushstateに対応したフロントエンドルーティングライブラリ
サンプルコード
タブメニューをクリックするとページコンテンツが切り替わります。
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"/>
</head>
<body>
<div class="jumbotron">
<section id="header">
<h1>KnockoutHx Sample</h1>
<p>Knockoutjs + Haxe sample application.</p>
</section>
</div>
<div class="container">
<div class="row">
<div class="col-md-12">
<section id="menu">
<ul class="nav nav-tabs nav-justified" data-bind="foreach: menus">
<li role="presentation" data-bind="css: { active: is_active }">
<a data-bind="text: name, attr: { href: url }, click: movePage">Top</a>
</li>
</ul>
</section>
<section id="contents">
<h1 data-bind="text: title"></h1>
<p data-bind="text: body"></p>
</section>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script>
<script src="app.js"></script>
</body>
import js.Browser;
import knockout.Knockout;
import knockout.Observable;
import routerhx.Router;
typedef Menu = {
name: String,
url: String,
is_active: Observable<Bool>,
movePage: Void -> Void
}
typedef Contens = {
title: Observable<String>,
body: Observable<String>
}
class Main {
static var menus: Array<Menu> = [
{ name: "Top", url: "/", is_active: Knockout.observable(true), movePage: topPage },
{ name: "Outline", url: "/outline", is_active: Knockout.observable(false), movePage: outlinePage },
];
static var contents: Contens = {
title: Knockout.observable(""),
body: Knockout.observable("")
}
static function main() {
var menu_dom = Browser.document.getElementById("menu");
var contents_dom = Browser.document.getElementById("contents");
Knockout.applyBindings({ menus: menus }, menu_dom);
Knockout.applyBindings(contents, contents_dom);
var r = new Router();
for (menu in menus) {
r.addCb(menu.url, menu.movePage);
}
r.raisePushState("a", "click", "href", menu_dom);
r.run();
}
public static function topPage(): Void {
switchActiveMenu("/");
contents.title.set("トップページ");
contents.body.set("トップページっぽいテキスト");
}
public static function outlinePage(): Void {
switchActiveMenu("/outline");
contents.title.set("概要");
contents.body.set("概要ページっぽいテキスト");
}
static function switchActiveMenu(target_url: String): Void {
for (menu in menus) {
if (menu.url == target_url && menu.is_active.get() == false) {
menu.is_active.set(true);
} else if (menu.url != target_url && menu.is_active.get() == true) {
menu.is_active.set(false);
}
}
}
}
Haxeで書く場合のポイント
- obserbしたプロパティへのアクセスは
get
、set
のアクセサを通して行う。 - ViewModelになる部分は予め
typedef
で構造を定義しておく(規模が大きいならクラスを定義する) - あとはリンクを踏んだ時の処理を好きなように書けばOK
昨日までに間に合いませんでした、スミマセンでした。