読者です 読者をやめる 読者になる 読者になる

ビールとプリンとプログラミング。

頭の悪いプログラマのぼやき。

javascriptのフレームワーク「Knockout.js」

みなさん、お疲れ様です。

ということで、
本日は
バルテック アドベントカレンダー2015 Advent Calendar 2015 - Adventar
投稿記事です。

『ITに関連するタメになる知識やタメになるサイトの紹介』

と言える記事になるかはわかりませんが、入社して1年目にとあるプロジェクトで出会ったKnockout.jsを紹介したいと思います。


javascriptフレームワークといえば、みんな大好きjQuery
現在、プログラミング研修中の方はピンと来ないかもしれませんが、javascriptにもJAVAPHPのようにフレームワークと呼ばれるものがあります。初めて出会うと、感動します。

そんな、みんな大好きjQueryとも共存できるフレームワークがKnockoutさんです。
私が初めてプログラマとして入った新規開発のプロジェクトで使っていたのですが、プロジェクトで働いていた諸先輩方もKnockout.jsを初めて使うようで、あまり使われていないフレームワークなのかなあと思いつつも、私にとってみれば、jQueryより先に出会ったフレームワークなので、世界に広まれ!と願っています。
なんか初めてって、好きになりますよね。理由なく。

◆Knockout.jsって何?

さて、Knockout.jsとはどんなフレームワークなのでしょうか。
それを知るのに最適なウェブサイトがこちらです。

kojs.sukobuto.com

本家ウェブサイトを鋭意翻訳してくださっているサイトです。
本命中の本命のウェブサイトですが、わからなくなったらココ探れば色々と何とかなります。
私は英語が苦手なので、このドキュメントが頼りです。

◆動かしてみよう

Knockout.jsがどんなフレームワークであるかという事を文章で書けるほど精通していないし、技術もありませんので、実際にどんな動きするのかを軽くやってみようかと思います。



基本的なこととして、Knockout.jsはViewModelというオブジェクトを作り、そのデータをHTMLのDOMにバインドさせて利用します。

まずはjavascriptの方はこんなイメージ。

// ユーザーオブジェクトを定義します。
var UserObject = function() {
  this.name = ko.observable("");
  this.age = ko.observable("");
};

// ViewModelを定義します。
var ViewModel = function() {
  this.user = new UserObject();
};

// ViewModelを生成します。
var viewModel = new ViewModel();

// DOM構築後にviewModelをバインドします。
$(document).ready(function(){
  ko.applyBindings(viewModel);
});

そしてHTMLはこんなイメージ。

…省略…
<div>
  名前を入力してください。<br />
  <input type="text" data-bind="value: user.name" />
</div>
<div>
  わたしの名前は<span style="color: red;" data-bind="text: user.name"></span>です。
</div>
…省略…


実際に動かすと下のような動きをします。テキストボックスに適当な値を入れてフォーカスを外してみてください。

名前を入力してください。
わたしの名前はです。



はい、何の意味もないウェブサイトの完成です!

ポイントは、

  • HTMLのDOMと連携したいデータの変数をko.observable("**ここに値**")にする。
  • ko.observable()にした変数はすべてのDOMを構築した後にko.applyBindings()でバインドする。(今回はjQuery使ってますが、htmlの一番下に置くだけで問題ないはずです。)
  • HTML上にdata-bind="value: user.name"data-bind="text: user.name"を記載するだけで値の変更を自動的に反映してくれる。

と、いった感じでしょうか。
これをjQueryでやると、inputのDOMをとってきて、inputのchangeイベントで、spanのDOMをとってきて、textメソッドで反映する!みたいなことを書かないといけませんね。

入力したデータは、もちろんjavascript内でも違和感なく使用できます。

alert("私は" + viewModel.user.name() + "です!");

といった具合に。 やってみる

◆配列も簡単

ko.observableArray()を使用すれば直感的に配列を扱えます。追加や削除といった操作を簡単に行うことができ、追加・削除の結果を自動的に反映してくれます。HTML上で簡単に繰り返しデータを扱うことができるのです。

// さっきのViewModelを改築します。
viewModel.users = ko.observableArray();
viewModel.push = function() {
  // 新たに追加するユーザーオブジェクトを生成します。
  var newUser = new UserObject();
  newUser.name = viewModel.user.name();
  newUser.age = viewModel.user.age();
  viewModel.users.push(newUser);
  
  // 入力用のユーザーオブジェクトは初期化します。
  viewModel.user.name("");
  viewModel.user.age("");
};
viewModel.remove = function(user) {
  // 第1引数にはforeach中の各オブジェクトが渡されます。
  viewModel.users.remove(user);
};
…省略…
<div>
  名前<input type="text" data-bind="value: user.name" />
  年齢<input type="text" data-bind="value: user.age" />
  <button data-bind="click: push">追加する</button>
</div>
<table style="border-style:dush" data-bind="foreach: users">
  <tr>
    <td>名前:<span data-bind="text: name"></td>
    <td>年齢:<span data-bind="text: age"></td>
    <td><button data-bind="click: $parent.remove">削除する</button></td>
  </tr>
</table>
…省略…


名前 年齢
名前: 年齢:

こんな感じですかね。適当に触ってみてください。
多分jQueryだと、javascriptでDOM生成を自分で書くことになりますが、Knockoutでは意識する必要がないです。

◆ということで

今までjQueryを使用し続けて居た方にしてみれば慣れるまで少し大変だったようです。ですが、慣れてしまうとKnockoutの方がわかりやすいと個人的には思っています。
JAVAPHPで静的なページを生成する場合は、そこまで重宝されないかもしれませんが、jQueryajaxで動くページの構築には力を発揮してくれるのではないでしょうか。


注意点としてはjQuery等で操作しているDOMにKnockoutでバインドしたデータを使わないことですかね。
逆にKnockoutが操作するDOMに対して、なるべくjQueryで他の場所から操作を行うのも避けたほうがいいです。
やれますけど、用心深くするべきです。わりと辛いです。





なかなかKnockout.jsを使用する場面というのはないのかもしれませんが、

今後参加するプロジェクトで「Knockout.js」という単語を見たときに、ふと思い出していただけると幸いです。




以上!