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 回答