しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Knockout.js 3.2.0 がリリースされたので新機能について一通り調べてみた

最近はあまり Knockout.js についてブログを書いてませんが、超特大なアップデートを含む 3.2.0 がリリースされたので、新機能について調べておきました。

Knockout 3.2.0 released - Steve Sanderson’s blog - As seen on YouTube™

それぞれの新機能について紹介していきます。

Components

Components は個人的には ASP.NET のサーバーコントロールとか MVC の部分ビューが近い気がしてます。HTML と ViewModel というペアを 1 つのコンポーネントとして扱えるようになるので、今まで以上に簡単に再利用可能なパーツとして定義できます。

サンプルとして、はてなブックマークのエントリ情報を読み込むようなコンポーネントを作ってみました。

レンダリングするコンポーネントは、新しく追加された component バインディングを使って指定できます。

params の url に表示したい URL を指定すると、それに関連付いたはてなブックマークのエントリ情報とブックマークコメントを表示するようになっています。サイドバーなどのウィジェットやソーシャルパーツの共通化に力を発揮すると思います。

Custom elements

前の Components では component バインディングを使ってコンポーネントをレンダリングするようにしましたが、独自の要素を使ってレンダリングを行うことも出来るようになりました。

書き方的にはより ASP.NET のサーバーコントロールっぽくなったと思います。コンポーネントに渡すパラメーターは params 属性に書けるので、component バインディングを使うよりもシンプルです。

Pure computeds

多分、新機能の中で一番分かりにくいと思うのが、この Pure computeds だと思います。とりあえず、簡単なサンプルを用意してみたので試してみると分かりやすいかもしれません。

具体的な挙動の違いとしては ko.pureComputed を使った場合は値の更新が行われていませんが、ko.computed を使った場合は値の更新が行われています。

そして、ko.computed を使った部分は以下のようなコードになります。

self.tempFullName = ko.computed(function () {
    var value = self.firstName() + " " + self.lastName();
    
    self.fullName(value);
    
    return value;
});
self.tempFullNamePure = ko.pureComputed(function () {
    var value = self.firstName() + " " + self.lastName();
        
    self.fullNamePure(value);
        
    return value;
});

今回のコードは computed の内部で別のプロパティに対して値の更新を行うようにしています。あえて tempFullNamePure は DOM にバインドしないようにしていますが、バインドしていない場合には引数で指定した関数が実行されません。

関数が呼び出される回数が削減されるのと、依存関係の解決がシンプルになるので CPU 使用率を削減し、メモリリークを改善できるというからくりのようです。

textInput binding

これまでテキストボックスやテキストエリアに対しては value バインディングを使っていましたが、value バインディングはデフォルトではフォーカスが失われたタイミングでのみ更新されていました。

しかし、テキストボックスではキーを押したタイミングやコピー&ペーストをした時でも、リアルタイムに値を反映したいことが割とあります。そういったケースには value バインディングではなく textInput バインディングを使うことで簡単に解決できるようになりました。

Twitter のような入力可能文字数を表示するインターフェースなども、textInput バインディングと ko.computed を使うことで簡単に実装出来ますね。

今回の目玉はやはり Components だと思っていましたが、地味に textInput バインディングも使い勝手が良い機能だと思いました。