Knockout を用いた
Firefox OS アプリケーションの開発
iizukak(いいづかけー)

第4回関東 Firefox OS 勉強会発表資料(2013/10/16)
自己紹介

✤

iizukak(いいづかけー)
✤

✤

ソフトウェアエンジニア @ 六本木
✤

✤

Github, Qiita, Twitter

JS をたくさん書くお仕事

プログラミングとボルダリングが好き
今日お話しすること

✤

MV* フレームワークあれこれ

✤

Knockout の紹介

✤

Knockout を用いた Firefox OS アプリの開発

前半は Firefox OS とあまり関係ないですが、お付き合いください
MV* フレームワークあれこれ
MV* フレームワークあれこれ

✤

JS の MV* フレームワークとされるライブラリは数多い

✤

そもそも、MV* フレームワークはなぜ必要?
MV* フレームワークあれこれ

✤

Firefox OS アプリ含め、最近の JS 開発では、モデルの状態を、動
的にビューに反映することは必須
①アイコンタップ

ユーザー

②イベント通知
③モデルの
 状態が変化

JS
④ビューに反映
MV* フレームワークあれこれ

✤

モデルのデータをビューと結びつける =「データバインド」

✤

データバインドを自力で書くのは割と面倒

✤

動的にビューをいじる仕組み作りが面倒

✤

コードの総量も増えがち
MV* フレームワークあれこれ

✤

MV* フレームワークの多くが、データバインド機能を提供
✤

✤

Knockout : デフォルトである

✤

✤

Angular : デフォルトである

Backbone : Epoxy.js とか使ってやる

MV* フレームワークは、データバインド機能を中心に、コードを構
造化する手助けをするライブラリ(※個人的見解です)
MV* フレームワークあれこれ
✤

デザインパターンの話がないぞ!というお客様へ

Backbone
Knockout

✤

MVVM : Model-View-ViewModel

Angular
✤

MVC

: Model-View-Controller

MVW : Model-View-Whatever

MV* の定義は人や本によってまちまち
各々のフレームワークが提案する使い方に従ってコードを書けば、デ
ザパタについてはそんなに悩まなくても良い(※個人的見解です)
Knockout の紹介
Knockout の紹介

✤

特徴
✤

✤

宣言的データバインド

✤

動的なビュー書き換えの実装サポート

✤

✤

Model-View-ViewModel デザインパターン

拡張製が高い

抽象的なので、実際の利用例で説明します
Knockout の紹介
✤

宣言的データバインドの例:名前を表示するアプリ
HTML
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>

JavaScript
function AppViewModel() {
this.firstName = "山田";
this.lastName = "太郎";
}
ko.applyBindings(new AppViewModel());

出力
Knockout の紹介
✤

いじくりたいタグに data-bind 属性を記述
HTML

strong タグをいじりたい

<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>

JavaScript
function AppViewModel() {
this.firstName = "山田";
this.lastName = "太郎";
}
ko.applyBindings(new AppViewModel());

出力
Knockout の紹介
✤

データバインドの種類を書く
HTML

テキストを挿入: text

<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>

JavaScript
function AppViewModel() {
this.firstName = "山田";
this.lastName = "太郎";
}
ko.applyBindings(new AppViewModel());

出力
Knockout の紹介
✤

適用したい変数名を適当に決める
HTML

firstName, lastName にする

<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>

JavaScript
function AppViewModel() {
this.firstName = "山田";
this.lastName = "太郎";
}
ko.applyBindings(new AppViewModel());

出力
Knockout の紹介
✤

ビューに適用する変数を持つコンストラクタを宣言
HTML
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>

JavaScript

コンストラクタに
firstName, lastName 変数を用意
出力

function AppViewModel() {
this.firstName = "山田";
this.lastName = "太郎";
}
ko.applyBindings(new AppViewModel());
Knockout の紹介
✤

ko.applybinding メソッドを呼んだタイミングで有効化
HTML
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>

JavaScript

バインドを起動

function AppViewModel() {
this.firstName = "山田";
this.lastName = "太郎";
}
ko.applyBindings(new AppViewModel());

出力
Knockout の紹介
✤

データバインドは、一般的にこんなかんじで記述
HTML
<開始タグ data-bind="データバインドの種類: 適用する変数名"></終了タグ>

JavaScript
function コンストラクタ() {
this.適用する変数 = 値;
}
ko.applyBindings(new コンストラクタ());
Knockout の紹介

✤

宣言的データバインドの良さ
✤

HTML を見ればどこの要素がいじられるのか明瞭

✤

デザイナーさんと分業しやすい
✤

✤

「ここは JS で制御する部分だからいじくらんでおこう…」

data-* 属性は正当な HTML 属性のため、実装した HTML が
validな HTML になり、気分がよい
Knockout の紹介
✤

組み込みデータバインドをいくつか紹介

click binding

クリックイベントをハンドリング

css binding

CSS を適用

visible binding 表示・非表示切り替え
if binding

if 文による分岐
Knockout の紹介
✤

動的なビュー操作の実装サポート
HTML
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>

JavaScript
function AppViewModel() {
this.firstName = ko.observable();
this.lastName = ko.observable();
}

出力
Knockout の紹介
✤

ユーザの名前入力に従って、表示内容を変更したい
HTML
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>

JavaScript
function AppViewModel() {
this.firstName = ko.observable();
this.lastName = ko.observable();
}

出力
Knockout の紹介
✤

コンストラクタに、ko.observable という変数を宣言
HTML
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>

JavaScript

observable な変数を宣言

function AppViewModel() {
this.firstName = ko.observable();
this.lastName = ko.observable();
}

出力
Knockout の紹介
✤

ユーザが苗字と名前を入力
HTML
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
<p>First name: <input data-bind="value: firstName" /></p>
ユーザが値を入力
<p>Last name: <input data-bind="value: lastName" /></p>

JavaScript
function AppViewModel() {
this.firstName = ko.observable();
this.lastName = ko.observable();
}

出力
Knockout の紹介
✤

書き換わったことが JS 側に通知され、変数が書き換わる
HTML
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input 変数の値が書き換わる
data-bind="value: lastName" /></p>

JavaScript
function AppViewModel() {
this.firstName = ko.observable();
this.lastName = ko.observable();
}

出力
Knockout の紹介
✤

ビューが動的に書き換わる
HTML
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
<p>First name: <input data-bind="value: firstName" /></p>
ビューを動的に書き換えてくれる
<p>Last name: <input data-bind="value: lastName" /></p>

JavaScript
function AppViewModel() {
this.firstName = ko.observable();
this.lastName = ko.observable();
}

出力
Knockout の紹介

✤

その他の特徴
✤

MIT ライセンス

✤

組み込みバインディングで物足りなくなったら、自作できる

✤

割と高速 (Android 2.x 世代の端末でもそれなりに動く)

✤

テストが書きやすい
✤

Knockout 本体も Jasmine を使ってテストされている
Knockout の紹介

✤

お仕事での実例
✤

iPhone, Android 向けネイティブゲームアプリ

✤

UI はほぼ全て WebView で実装

✤

規模:HTML 200 画面、JS 数万行

✤

モデルの変更・ビューの書き換えが非常に多い
✤

Knockout を活用。自作 binding も数十個
Knockout を用いた
Firefox OS アプリの開発
Firefox OS アプリへの組み込み

✤

試作アプリ
✤

✤

OAuth 認証

✤

✤

簡易 Twitter クライアント

タイムライン表示

Github へのリンク
Firefox OS アプリへの組み込み
✤

UI は Firefox OS Building Blocks ライブラリ
Firefox OS アプリへの組み込み
✤

アプリケーションの全体像
FxOS クライアント

データバインド
・TL情報
・ファボ情報
・タップイベント発火

APIサーバ

メソッド呼び出し

ViewModel

・TL 取得メソッド
・ツイートメソッド

Model

API
通信

View
UI ロジック

VIew の状態を管理

ビジネスロジック

Twitter
API
Firefox OS アプリへの組み込み

✤

Knockout 使っている場所

✤

タイムラインをリスト表示するとこ
✤

foreach-binding
✤

ko.observableArray

✤

text-binding

✤

attr-binding
Firefox OS アプリへの組み込み

✤

感想
✤

非常に素直に導入できた

✤

「あ、これ Knockout を使って簡単に書けるやつだ」が多い
✤

✤

タイムラインへの新規ツイートの挿入が容易に実装できた

MVVM がアプリの要件にマッチ
✤

MVVM はそもそもが GUI アプリ向けのデザインパターン
まとめ
まとめ

✤

MV* フレームワーク
✤

✤

データバインドを中心に、プログラムの構造化を手助け

Knockout
✤

✤

✤

宣言的データバインド
動的なビュー書き換えの実装サポート

Firefox OS アプリケーションの開発にも適してそう

Knockout を用いた Firefox OS アプリケーションの開発