#Backbone.js Advent Calendar 2日目!
勢い良く走り始めたBackbone.js Advent Calendarですが、初日に引き続き2日目もビューに関連する話題です。
##ビューの遅延評価をしたい
Backbone.jsに限らずサービスを高速化するために、遅延評価を行いたい場面は沢山あります。たとえば画像掲示板のシステムを作っていたら、いきなり画像全てを読み込もうとするとサーバにも負荷がかかりますし、何よりユーザが表示しない画像まで読み込むのは無駄です。他にもTwitterのようなタイムラインに対して、一番下までユーザがスクロールしたら自動的に続きを読み込むような処理を行いたい場合もあるでしょう。
という訳でユーザのスクロールをトリガーにしてイベントを発火させられるBackbone.LazyView
というのを作ってみました。
###簡単な使い方
lazyview.js
を読み込むとBackbone.LazyView
というオブジェクトがBackboneに追加されます。このオブジェクトはBackbone.View
と全く同じインタフェースを持ちます。唯一の違いはel
プロパティが指すエレメントがブラウザ上に現れたらappear
というイベントが発行されることです。
使い方は通常のBackbone.View
と全く同じです。
var FooLazyView = Backbone.LazyView.extend({
events: {
"appear": "appear"
},
initialize: function () {
_.bindAll(this, "appear");
},
appear: function () {
/* ここに処理を書く */
alert("hoge");
}
});
あとはFooLazyView
コンストラクタを使ってオブジェクトを生成するだけです。
var view = new FooLazyView({el: $("#foo")});
これで$("#foo")
要素がブラウザに表示された瞬間にview.appear
が実行されてhogeとアラートされます。代わりにimgタグのsrc属性を書き換えたり、Ajaxによる読み込みを行う処理を記述すれば遅延評価の完成です。
##Viewのクラスプロパティを使う
上記だけだと寂しいので、ちょっとした小ネタを紹介します。
例えばBackbone.Viewのrenderメソッド内でunderscore.jsのtemplate機能を使うというのはよくあるパターンだと思いますが、レンダリングの度にjQueryを使ってテンプレートをわざわざ取ってくるのもなんか嫌な感じですよね。こういう場合はクラスプロパティにテンプレートを文字列として保存したくなります。例えばこんな感じに書くかも知れません。
var SomeView = Backbone.View.extend({
initialize: function () {
_.bindAll(this, "render");
},
render: function () {
$(this.el).html(_.template(SomeView.template, this.model));
}
});
SomeView.template = $("#template-of-some-view").html();
もちろんこれでも問題ありませんが、下記のように書くこともできます。
var SomeView = Backbone.View.extend({
initialize: function () {
_.bindAll(this, "render");
},
render: function () {
$(this.el).html(_.template(SomeView.template, this.model));
}
}, { // クラスプロパティになる
template: $("#template-of-some-view").html()
});
テンプレートを動的に選択したり、JSのロード時にDOM上にテンプレートが存在しない場合などは、underscore.jsのmemoizeなどを使ってもいいかも。
var SomeView = Backbone.View.extend({
initialize: function () {
_.bindAll(this, "render");
},
render: function () {
$(this.el).html(_.template(SomeView.getTemplate("#template-of-some-view"), this.model));
}
}, {
getTemplate: _.memoize(function (q) { return $(q).html() })
});
このようにextendメソッドの第二引数に渡されたオブジェクトがクラスプロパティになります。Viewに限らずModelやController、上で紹介したLazyViewでも同様です。