なんとかして.NET以外でもMVVMできないか調べていた
たぶん知らないだけなのかもしれませんが、MVVMといえばWPF以外ではあんまり聞かないなって思ってました。私の観測範囲での話ですが、MVVM自体WPFでの開発スタイルをさして新しくできた単語みたいなイメージなので、まあそうなのかなーと。でもWPFが世に出て5年以上が経った今、ひょっとしたら他のところでもMVVMできるのでは?と思ってたらありました。
JavaScriptのフレームワーク「knockout.js」
knockout.jsはObserveパターンとバインディングの実現を二本柱とした軽量フレームワークです。ビュー側のマーカーにHTML5で追加されたデータコンテキストを使うので、HTML5のバリデーターが通るのもよいところ。Angular.jsはHTML5にない独自の属性を使ってマーキングしているのでバリデーターに通りません。まあバリデーション通すのってある種の自己満足的なところがなくもないのですが
基本的な使い方
ko.observableとsubscribe
最初のやつで変更を通知できるようになります。これとsubscribeを組み合わせると、値がかわったときに何かする、というのができるようになります。
var value = 1; //こう書くところを var value = ko.observable(1); //こう書くと値がかわったことを知ることができるようになる var val = value() //値を取得する value(2) //値を設定する
これだとまだとくにおいしいところはないので、subscribeを使ってみましょう。
value.subscribe(function(newValue) { alert(newValue); }, this); //値が変更されるとアラートが表示される
こうしておくと、valueの値が変更されると執拗にアラートでお知らせしてくれます。
他にも、配列の値を監視できるようにするobservableArray、演算結果を監視するcomputedもあります。だいたい使い方は同じです。
バインディング
<article id="target"> <h1 data-bind="value: title"></h1> <div data-bind="value: body"></div> </article>
みたいな感じにマークアップして、
function ViewModel(title, body) { this.title = title; this.body = body; }
というVIewModelを作成して、
var vm = new ViewModel("2%", "アキラメナーイ"); ko.applyBindings(vm, document.querySelector("#target"));
とバインドする場所を指定します。