覆盖主干网.js比较器

Overriding Backbone.js comparator

本文关键字:比较器 js 主干网 覆盖      更新时间:2023-09-26

我有一个简单的主干.js推特应用程序,需要以相反的顺序对推文进行排序。我目前已经实现了按日期排序的比较器。单击"反向"按钮(如视图中所示)时,如何在不返回比较器的情况下对所有推文进行反向排序?我的印象是,当我调用排序时,它会尝试重新呈现列表(这意味着比较器将再次对数据进行排序,这是不可取的)。如何覆盖它?

Tweet = Backbone.Model.extend();
 // Define the collection
Tweets = Backbone.Collection.extend(
{
    model: Tweet,
    // Url to request when fetch() is called
    url: 'http://search.twitter.com/search.json?q=codinghorror',
    parse: function(response) {
        //modify dates to be more readable
        $.each(response.results, function(i,val) {
            val.created_at = val.created_at.slice(0, val.created_at.length - 6);
          });
        return response.results;
    },
    // Overwrite the sync method to pass over the Same Origin Policy
    sync: function(method, model, options) {
        var that = this;
            var params = _.extend({
                type: 'GET',
                dataType: 'jsonp',
                url: that.url,
                processData: true
            }, options);
        return $.ajax(params);
    },
    comparator: function(activity){
        var date = new Date(activity.get('created_at'));
        return -date.getTime();
    }
});
   // Define the View
  TweetsView = Backbone.View.extend({
initialize: function() {
  _.bindAll(this, 'render');
  // create a collection
  this.collection = new Tweets;
  // Fetch the collection and call render() method
  var that = this;
  this.collection.fetch({
    success: function (s) {
        console.log("fetched", s);
        that.render();
    }
  });
},
el: $('#tweetContainer'),
// Use an external template
template: _.template($('#tweettemplate').html()),
render: function() {
    // Fill the html with the template and the collection
    $(this.el).html(this.template({ tweets: this.collection.toJSON() }));
},
events : {
    'click .refresh' : 'refresh',
    **'click .reverse' : 'reverse'**
},
refresh : function() {
 this.collection.fetch();
console.log('refresh', this.collection);
 this.render();
},
**reverse : function() {**
    console.log("you clicked reverse");
    console.log(this.collection, "collection");
    this.collection.sort();
   //How do I reverse the list without going through the comparator?
**}**
});
var app = new TweetsView();
 });

主干问题的通常解决方案是使用事件。调用sort将触发"reset"事件:

调用排序会触发集合的"reset"事件,除非通过传递 {silent: true} 来静音。

因此,您可以在集合中有一个"排序顺序"标志:

Backbone.Collection.extend({
    //...
    initialize: function() {
        //...
        this.sort_order = 'desc';
        //...
    }
});

然后你的comparator可以注意那个标志:

comparator: function(activity) {
    var date = new Date(activity.get('created_at'));
    return this.sort_order == 'desc'
         ? -date.getTime()
         :  date.getTime()
}

您可以在集合上有一个方法来更改排序顺序:

reverse: function() {
    this.sort_order = this.sort_order = 'desc' ? 'asc' : 'desc';
    this.sort();
}

然后,视图可以侦听"reset"事件,并在更改排序顺序时重新显示集合。一旦一切都到位,你只需告诉你是你的反向按钮来呼叫view.collection.reverse()一切都会好起来的。

演示:http://jsfiddle.net/ambiguous/SJDKy/