获取由其他集合组成的Backbone.Collection

时间:2013-11-07 00:47:26

标签: backbone.js collections

所以我有几种类型的数据:

Post Project Event

每个数据模型都有自己的集合和查看它们的路径:

/posts    => app.postsCollection
/projects => app.projectsCollection
/events   => app.eventsCollection

现在我想添加另一条路线:

/ => app.everythingCollection

如何创建一个显示其他三个集合的集合的集合,但不再提取所有的后期项目和事件数据

同样,调用everythingCollection.fetch()会填充postsCollectionprojectsCollectioneventsCollection,以便他们的数据在独立呈现时可用。

重点是永远不要两次下载相同的数据。

4 个答案:

答案 0 :(得分:1)

您的app.everythingCollection不一定是真正的骨干集合。它只需要访问获取到其他馆藏。

您可以继承Backbone.Events以获得所有活动设施。

var fetchedRecords = {posts: 0, projects: 0, events: 0};
var Everything = function () {}
_.extend(Everything.prototype, Backbone.Events, {
    fetch: function (option) {
      that = this;
      this.count = 0;
      option.success = function () {that.doneFetch(arguments)};
      if (fetchRecords.posts == 0) {
        option.fetchedName = "posts";
        app.postsCollection.fetch(option);
        this.count ++;
      }
      if (fetchRecords.projects == 0) {
        option.fetchedName = "projects";
        app.projectsCollection.fetch(option);
        this.count ++;
      }
      if (fetchRecords.events == 0) {
        option.fetchedName = "events";
        app.eventsCollection.fetch(option);
        this.count ++;
      }
    },
    donefetch: function (collection, response, options) {
      if (this.count <=0) return;
      this.count --;
      if (this.count == 0) {
        if (options.reset) this.trigger("reset");
      }
      fetchedRecords[options.fetchedName] ++;
    },
    posts: function () {return app.postsCollection},
    projects: function () {return app.projectsCollection},
    events: function () {return app.eventsCollection}
});

app.everythingCollection = new Everything;
everythingView.listenOn app.everythingCollection, "reset", everythingView.render;
app.everythingCollection.fetch({reset: true});

您需要递增fetchedRecrods次计数以防止多次抓取。 像这样的东西。代码未经测试。但想法是一样的。

答案 1 :(得分:0)

var EverythingCollection = Backbone.Model.extend({

customFetch: function (){

    var collections = [app.postsCollection, app.projectsCollection, app.eventsCollection],
        index = -1,
        collection,
        that = this;

    this.reset(); //clear everything collection.

    //this function check collections one by one whether they have data or not. If collection don't have any data, go and fetch it.
    function checkCollection() {            
        if (index >= collections.length) { //at this point all collections have data.
            fillEverything();
            return;
        }

        index = index + 1;            
        collection = collections[index];

        if (collection && collection.models.length === 0) { //if no data in collection.
            collection.fetch({success: function () {
                checkCollection();
            }}); 
        } else { //if collection have data already, go to next collection.
            checkCollection();
        }
    }

    function fillEverything() {
        collections.forEach(function (collection) {                
            if (collection) {
                that.add(collection.models); //refer this http://backbonejs.org/#Collection-add
            }
        });
    }
 }
});

使用如下。

app.everythingCollection = new EverythingCollection();
app.everythingCollection.customFetch();

对于其他集合,请在获取数据前检查models长度。像下面的东西。

if (app.postsCollection.models.length === 0) {
    app.postsCollection.fetch();
}

答案 2 :(得分:0)

在app启动时将所有必要的集合存储在数组或对象中,将事件侦听器附加到每个侦听第一个重置事件并记住在第二个数组中获取的集合。如果使用了您需要所有集合的路由,则可以获取已在已获取的集合中找到的数组:

(未经测试,但它会让你知道如何做到这一点)

var allCollections = [app.postsCollection, app.projectsCollection, app.eventsCollection];
var fetchedCollections = [];

$.each(allCollection, function(i, coll){
  coll.once("reset", function(){
    fetchedCollections.push(coll);
  })
});

var fetchAll = function(){
    $.each(allCollections, function(i, coll){
       if( $.inArray(coll, fetchedCollections ) == -1 ){
         coll.fetch();
       }
    });
}

在everythingCollection中执行此操作,您将拥有所需的everythingCollection.fetchAll()功能。您还可以覆盖everythingCollection的fetch函数,以首先获取所有其他集合:

fetch(options){
  this.fetchAll();
  return Backbone.Collection.prototype.fetch.call(this, options);
}

答案 3 :(得分:0)

听起来braddunbar's supermodelbenvinegar's backbone.uniquemodel可能会解决您的问题

接下来建立Soundcloud时,还值得查看Soundcloud's article(参见在视图之间共享模型)。在解决这个问题时,他们对上述两个插件采用了类似的方法。