【问题标题】:Backbone.js: Differentiating Between a Collection That Is Still Loading and an Empty Collection?Backbone.js:区分仍在加载的集合和空集合?
【发布时间】:2012-10-10 02:03:26
【问题描述】:

使用 Backbone.js,我有一个我实例化的集合,X。实例化后,我立即调用X.fetch(),以便尽快从服务器加载数据。然后我将X 传递到将在集合上运行的各种视图中。

对于这些视图来说,区分集合只是加载(因此为空)和集合加载但实际上是空的最佳方式是什么?我希望我的视图显示适当的“正在加载...”文本,直到集合对服务器执行 ping 操作。此时,我想让他们说“这里好像什么都没有。也许你应该添加一些东西。”

我正在考虑在每个视图中收听集合上的reset 事件,但这对我来说似乎相当脆弱。如果在视图附加其侦听器之前重置事件已经触发,会发生什么?是否有一种很好的模式来检查集合的状态以了解它是否已被提取?

【问题讨论】:

    标签: javascript backbone.js


    【解决方案1】:

    fetch 方法是异步的,基于 AJAX 的异步特性。 因此,您需要实现事件驱动的行为。

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

    更新

    根据您对我的回答的 cmets,我可以提出另一个想法。 即你可以设置

    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);
        }
    });
    

    Documentation

    【讨论】:

    • 这似乎假设一个全局预加载器。如果我希望每个视图自己跟踪它们的预加载状态怎么办?在这种情况下,这是页面的一个子部分,所以我只是有条件地创建集合并将其传递到两个不同的小视图中。有没有办法简单地询问集合是否尝试加载自己?
    • 您的评论对我来说不是很清楚。你的意思是你从你的服务器为不同视图的不同集合获取相同的数据?
    • 是的,那个解释不是很好。以下是事件的顺序: 1) 页面加载。 2) 用户点击一个链接。 3) 这会触发新视图A 的创建。 A 创建集合并告诉它自己获取。然后它创建子视图xy 将集合传递给它们。 x 特别需要在集合加载时得到通知,以便它可以将其文本从“加载”更改为“空”。 A 对这种行为完全天真。我希望x 能够自己查看集合是否已加载。
    【解决方案2】:

    确保在调用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-05-10
      • 2012-10-30
      • 2011-12-17
      • 2011-08-31
      • 1970-01-01
      • 2012-03-13
      • 2011-08-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多