Backbone.js更新集合中的模型

时间:2011-03-24 23:53:52

标签: javascript jquery backbone.js

假设您正在使用Backbone.js构建Twitter克隆。你有一些推文。每条推文显然都是Tweet模型的一个实例。

您可以创建集合的实例,获取最新的10条推文,渲染它们并添加到DOM。

到目前为止一切顺利。

如果你想在几分钟后打电话给服务器看看是否有新的推文怎么办?如何将新到的推文添加到集合中?

如果您使用fetch()方法,则会始终使用相同的网址。没关系。有没有一种聪明的方法可以使用Backbone / Underscore来过滤那些并将不在集合中的推文添加到集合中?

5 个答案:

答案 0 :(得分:16)

让我们假设你的每条推文都有一个唯一的标识符(如果没有,你应该创建一个)。

你可以构建你的后端,默认情况下,如果你在没有任何参数的情况下调用http://your.site.com/tweets,它会获得10条最新的推文。

如果您拨打http://your.site.com/tweets?last_tweet_id=BLAblaBlA,它会在您指定的last_tweet_id之后提供10条最新推文。

您可以通过实现YourCollection.sync方法覆盖从后端获取数据到您的Collection中的代码。

原因:Backbone.Collection首先尝试调用Collection.sync,如果未实现,则调用Backbone.sync函数,因此如果实现YourCollection.sync,将使用它。以下是Backbone.Collection.fetch函数的片段:

(this.sync || Backbone.sync)('read', this, success, error);

所以你的同步就像是

var TweetCollection = Backbone.Collection.extend({
  model: TweetModel,
  sync: function(method, collection, success, error) {
    var requestData={};
    if(collection.length>0) {
        requestData.last_tweet_id=collection.last.id 
    }
    var params = {
        url:          "/tweet",
        type:         "POST",
        data:         requestData,
        success:      success,
        error:        error
    };
    $.ajax(params);
  }
}

您必须覆盖集合解析函数,以确保将响应附加到现有模型数组。

答案 1 :(得分:8)

我不确定这是否可能在3月回归,因为我最近才开始使用骨干网。但更好的解决方案可能是将标准jQuery选项传递给Collection.fetch。

this.collection.fetch({data: {last_tweet: last_teet_id}});

Check out the jQuery documentation for a full list of parameters.

答案 2 :(得分:2)

我相信这就是你要找的东西:

yourCollection.fetch({add: true})

然后,您可以将集合视图的渲染绑定到add事件:

yourCollectionView.bind('add', this.render, this);

但是,如果渲染很重,你会想要超时延迟它,以避免每次添加到集合时立即调用它:

yourCollectionView.bind('add', this.delayedRender, this);

delayedRender: function() {
  var self = this;
  if (self.renderTimer) { clearTimeout(self.renderTimer); }
  self.renderTimer = setTimeout(function() {
    self.render();
    self.renderTimer = null;
  }, 300);
}

答案 3 :(得分:0)

目前,开箱即用,没有。

我使用的技术如下。你有你的TweetCollection扩展Backbone.Collection它有一个经典的REST网址,如“/ tweets”。您的后端仅发送10条最新记录(或第1页)。要获得第2页,您将使用类似“/ tweets?page = 2”的网址,后端将发送下一条10条推文。问题是:在获取新记录时如何保留旧记录?

我使用了2个集合:

  • 第一个是用于在屏幕上呈现推文的那个。这是一个正常的TweetCollection。
  • 第二个是用于从服务器获取页面的那个。我们称之为TweetPageCollection。

TweetPageCollection使用以下网址扩展TweetCollection:

 page: 1,
 url : function(){ return "/tweets?page=" + this.page; }

现在在您的控制器代码中,您可以执行以下操作:

initialize: function(){
  this.tweets = new TweetCollection();
  this.pages = new TweetPageCollection();
  this.pages.bind("refresh", this.newPageReceived);

  this.pages.page = 1;
  this.pages.fetch();

  this.tweet_list_view = new TweetListView({model: this.tweets});
},
getNextPage: function(){
  this.pages.page++;
  this.pages.fetch();
},
newPageReceived : function(page){
  // here you can check that the tweet is not already in the tweets collections
  this.tweets.add(page.toArray());
}
...

现在,当您想要获取新推文时,请调用getNextPage(),当XHR成功时,您的视图将被刷新。

可以应用相同的原则来重新获取最新的推文。 2个集合,1个抓取,其他聚集提取。

答案 4 :(得分:0)

我不认为这是一个骨干问题。使用Twitter的RESTful API,您可以使用可选的since_id参数。每次调用后,您的收藏集都可以保存已获取的最新推文的ID。在您的网址功能中使用此ID,您只会收到较新的推文。