1

Backbone.jsを使用して、インスタンス化するコレクションがありXます。インスタンス化した後、X.fetch()すぐにサーバーからデータをできるだけ早くロードできるように呼び出しました。次にX、コレクションを操作するさまざまなビューに移ります。

これらのビューの最良の方法は、コレクションが単にロードされている(したがって空である)場合と、ロードされているが実際には空である場合を区別する方法は何ですか?コレクションがサーバーにpingを実行するまで、ビューに適切な「読み込み中...」テキストを表示したいと思います。その時点で、「ここには何もないようです。何か追加する必要があるかもしれません」と言ってもらいたいと思います。

resetそれぞれの視点でコレクションのイベントを聴こうかと思っていたのですが、なかなか壊れそうです。ビューがリスナーをアタッチする前にリセットイベントがすでに発生している場合はどうなりますか?コレクションの状態を調べて、それがフェッチされているかどうかを確認するための適切なパターンはありますか?

4

2 に答える 2

3

fetchメソッドは、AJAXの非同期性に基づいて非同期です。したがって、イベント駆動型の動作を実装する必要があります。

X.fetch({
    success: function(collection, response) {
        hidePreLoader();
        renderViews(collection); // collection argument is your X collection.
    }
});

アップデート

私の答えに対するあなたのコメントに基づいて、私は別のアイデアを提案することができます。つまり、設定することができます

X.isLoaded = true;

またはのような他のプロパティ

X.loadedAt = Date.now();

successコールバックで、他のコードがこのプロパティの状態をチェックできるようにします。

しかし、私はここで一種の悪いデザインを見ますが。プリローダーを表示してビューをレンダリングでき、successコールバックトリガーで、ビューが読み込まれて使用できるようになったため、コレクションでビューが機能し始めるイベントがトリガーされます。したがって、全体として、イベント駆動型の動作を使用することを再度提案します。

私はテストしませんでしたが、ここに私の考えの表現があります:

var XCollection = Backbone.Collection.extend({

    // ...

    model: X,
    loadState: {},
    loadedAt: -1,
    initialize: function(options) {
        _.extend(this.loadState, Backbone.Events);
    },

    isLoaded: function() {
        return this.loadedAt > -1;
    }
});

var Subview = Backbone.View.extend({

    // ...

    initialize: function(options) {
        this.collection.loadState.on("loadComplete",
            this.onLoadComplete, this);
    },

    onLoadComplete: function(response) {
        this.hidePreloader();
        this.renderData();
    },

    /**
     * Checks is the collection loaded and view can render fetched models.
     * It's just an example.
     * You'll not need to use it if you're handling a loadComplete event.
     */
    isRenderingAllowed: function() {
        return this.collection.isLoaded();
    }
});

var XView = Subview.extend({

    // ...

    initialize: function(options) {
        Subview.prototype.initialize.apply(this, arguments);
    }
});

var YView = Subview.extend({

    // ...

    initialize: function(options) {
        Subview.prototype.initialize.apply(this, arguments);
    }
});


// ...

var x = new XCollection();

var xView = new XView({collection: x}),
    yView = new YView({collection: x});

x.fetch({
    success: function(collection, response) {
        collection.loadedAt = Date.now();
        collection.loadState.trigger("loadComplete", response);
    }
});

ドキュメンテーション

于 2012-10-10T02:06:37.987 に答える
1

を呼び出す前に、必ずビューを初期化してくださいfetch()。このようにして、resetイベントをリッスンし、すべてのビューが更新されていることを確認できます。xlistをできるだけ早くロードしたい場合は、HTMLサーバー側にブートストラップすることをお勧めします。

それを行う方法は次のようになります。

<script src="/public/js/collecions/x-list.js">
<script src="/public/js/views/x-view.js">

    <script>
         var xlist = new App.Collections.XList();

        _.each($(".xdiv"), function(el){
             new App.Views.XView({
                 el: el,
                 collection: xlist
             });
             // make sure that XView have this in it's initialize method:
             // this.collection.bind("reset", this.render, this)
        }

        xlist.fetch();

        // or even better, use bootstraped data:

        x.list.reset((<%= @data.to_json %>)
    </script>
于 2012-10-10T10:10:38.397 に答える