Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
43
Help us understand the problem. What is going on with this article?
@yuku_t

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

More than 5 years have passed since last update.

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
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
yuku_t
FLYWHEEL社でソフトウェアエンジニアをしています。昔はIncrements社最初の従業員としてQiitaを開発したりCTOやったりしていました。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
43
Help us understand the problem. What is going on with this article?