0

我有一个 Backbone.js 项目,它使用集合中定义的比较器函数。它在页面刷新时对项目进行排序,但我试图在单击按钮而不是在页面刷新时对其进行排序。这是我的代码:

   var Thing = Backbone.Model.extend({
     defaults: {
         title: 'blank',
         rank: ''
     }
 });
 var ThingView = Backbone.View.extend({
    className: 'thingClass',
     template: _.template('<b><button id="remove">X</button> <b><button id="edit">Edit</button> <%= title %>  Rank:<%= rank %></b>'),
     editTemplate: _.template('<input class="name" value="<%= name %>" /><button id="save">Save</button>'),

     events: {
         "click #remove": "deleteItem",
         "click #edit": "editItem",
         "click #save": "saveItem",
     },
     deleteItem: function () {
         console.log('deleted');
         this.model.destroy();
         this.remove();
     },
     editItem: function () {
         console.log('editing');
         this.$el.html(this.editTemplate(this.model.toJSON()));
     },
     saveItem: function () {
         console.log('saved');
         editTitle = $('input.name').val();
         console.log(editTitle);
         this.model.save({
             title: editTitle
         });
         this.$el.html(this.template(this.model.toJSON()));
     },
     render: function () {
         var attributes = this.model.toJSON();
         //console.log (attributes);
         this.$el.append(this.template(attributes));
         return this;
     }
 });
 var ThingsList = Backbone.Collection.extend({
     model: Thing,
     localStorage: new Store("store-name"),
     comparator: function(thing) {
     return thing.get('rank');
     },
 });

 var thingsList = new ThingsList;
 var ThingsListView = Backbone.View.extend({
     el: $('body'),
     events: {
         'click #add': 'insertItem',
         'click #sort': 'sortItems',
     },
     initialize: function () {
    thingsList.fetch();
    thingsList.toJSON();
         this.render();
         this.collection.on("add", this.renderThing, this);
         this.collection.on("reset", this.clearRender, this);
     },
     insertItem: function (e) {
         newTitle = $('#new-item').val();
         newRank = $('#rank').val();
         newThing = new Thing({
             title: newTitle,
             rank: newRank
         });
         this.collection.add(newThing);
         newThing.save();
         console.log(this.collection.length);
     },

     sortItems: function (e) {
        console.log('clicked sort button');
        this.collection.sort();
        this.$el.detach('.item');
     },

     render: function () {
         _.each(this.collection.models, function (items) {
             this.renderThing(items);
         }, this);

     },
     renderThing: function (items) {
         var thingView = new ThingView({
             model: items
         });
         this.$el.append(thingView.render().el);
     },

     clearRender: function () {
        console.log('clear render called')

         _.each(this.collection.models, function (items) {
             //this.remove();
             this.$el.remove(".thingClass")
             this.renderThing(items);
         }, this);

     },



     test: function (items) {
         console.log('test worked');
     },


 });
 var thingsListView = new ThingsListView({
     collection: thingsList
 });
4

1 回答 1

0

你确定你的收藏不是靠自己吗?请记住,如果模型已经呈现,集合中模型的顺序不会改变它们在页面上的显示顺序。

我猜您正在尝试做的是对已经渲染的项目进行处理,为此您需要重新渲染您的收藏。如果您打算这样做,我建议您缓存您的视图并在排序时从 DOM 中分离关联的元素并以正确的顺序重新附加它们。

举个例子

var ThingsListView = Backbone.View.extend({
  _views: {},

  initialize: function () {
        this.collection.bind('add', this.add, this);
        this.collection.bind('reset', this.render, this); //sort triggers a reset 
  },

  add: function (thing) {
    var view = new ThingView({model: thing});
    this._views[thing.cid] = view; //use client id of model as key for the views cache
    this.$el.append(view.render().el); 
  },

  render: function() {

    $('li, this.$el).detach(); //detach so that bound events aren't lost
    _.each(this.collection.models, function(thing) {        
        this.$el.append(this.views[thing.cid].el); //get view from cache
    },this);

  },

  sort: function() {
    this.collection.sort();
  }

}

})

(与我的示例代码和您的代码有一些不同之处,我在这里假设集合视图有一个 'el' 指代容器 'ul',我也没有显示您如何触发排序(基本上类似于thingListView.sort();)

编辑:从我发布的示例代码中可能不是那么明显,所以我应该先提到@Deeptechtons 所说的,当你对集合进行排序时,它会触发一个reset事件

Edit2:如果您对缓存视图不感兴趣,那么删除当前视图的最简单方法可能是向呈现的 div 添加一个类

var ThingView = Backbone.View.extend({
     className: 'thingClass',
   //rest of your thingViewCode

然后在您的 clearRender 方法中添加$(".thingClass", this.$el).remove();到方法的开头。

于 2012-07-02T15:06:40.037 回答