LoginSignup
43
43

More than 5 years have passed since last update.

ビューが画面に現れたら処理を実行する

Last updated at Posted at 2012-12-16

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でも同様です。

43
43
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43
43