Javascript Backbone.js:区分仍在加载的集合和空集合?

Javascript Backbone.js:区分仍在加载的集合和空集合?,javascript,backbone.js,Javascript,Backbone.js,使用Backbone.js,我有一个实例化的集合,X。实例化后,我立即调用X.fetch(),以便尽快从服务器加载数据。然后,我将X传递到将对集合进行操作的各种视图中 对于这些视图来说,当集合只是加载(因此为空)时,与当集合加载但实际为空时,它们之间的最佳区别是什么?我希望我的视图显示适当的“加载…”文本,直到集合ping到服务器。在这一点上,我希望他们说:“看起来这里什么都没有。也许你应该补充一些。” 我在考虑在每个视图中收听集合上的重置事件,但这对我来说似乎相当脆弱。如果在视图附加其侦听器之

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

对于这些视图来说,当集合只是加载(因此为空)时,与当集合加载但实际为空时,它们之间的最佳区别是什么?我希望我的视图显示适当的“加载…”文本,直到集合ping到服务器。在这一点上,我希望他们说:“看起来这里什么都没有。也许你应该补充一些。”


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

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
callback中触发一些事件,在这些事件上,您的视图将开始使用集合,因为集合已加载并准备好使用。 总之,我再次建议您使用事件驱动行为

X.fetch({
    success: function(collection, response) {
        hidePreLoader();
        renderViews(collection); // collection argument is your X collection.
    }
});
我没有测试,但以下是我的想法:

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

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
callback中触发一些事件,在这些事件上,您的视图将开始使用集合,因为集合已加载并准备好使用。 总之,我再次建议您使用事件驱动行为

X.fetch({
    success: function(collection, response) {
        hidePreLoader();
        renderViews(collection); // collection argument is your X collection.
    }
});
我没有测试,但以下是我的想法:

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

在调用
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>

var xlist=new App.Collections.xlist();
_.每个($(“.xdiv”)、函数(el){
新App.Views.XView({
艾尔:艾尔,
收藏:xlist
});
//确保XView在其初始化方法中包含以下内容:
//this.collection.bind(“重置”、this.render、this)
}
xlist.fetch();
//或者更好地使用引导数据:
x、 列表。重置()

确保在调用
fetch()
之前初始化视图。这样,您可以侦听
重置
事件,并确保所有视图都已更新。如果希望尽快加载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>

var xlist=new App.Collections.xlist();
_.每个($(“.xdiv”)、函数(el){
新App.Views.XView({
艾尔:艾尔,
收藏:xlist
});
//确保XView在其初始化方法中包含以下内容:
//this.collection.bind(“重置”、this.render、this)
}
xlist.fetch();
//或者更好地使用引导数据:
x、 列表。重置()

这似乎假设有一个全局预加载程序。如果我想让每个视图自己跟踪其预加载状态,该怎么办?在这种情况下,这是页面的一个子部分,因此我只能有条件地创建集合,并将其传递到两个不同的小视图中。是否无法简单地询问集合是否尝试加载自身?您的命令ent对我来说不清楚。你的意思是你从服务器上为不同视图中的不同集合获取相同的数据吗?是的,这个解释不是很好。事件顺序如下:1)页面加载。2)用户单击链接。3)这将触发新视图的创建
a
a
创建集合并告诉它自己提取。然后它创建子视图
x
y
将集合传递给它们。
x
尤其需要在集合已加载时得到通知,以便它可以将其文本从“加载”更改为“空的".
A
对这种行为完全是幼稚的。我希望
x
能够自己查看集合是否已加载。这似乎假设有一个全局预加载程序。如果我希望每个视图都跟踪其预加载状态,该怎么办?在这种情况下,这是页面的一个子部分,因此我只会有条件地创建集合并将其传递到两个不同的小视图中。是否无法简单地询问集合是否尝试加载自身?您的评论对我来说不清楚。您的意思是从您那里获取相同的数据