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

}

})

(私のサンプルコードとあなたのものとのいくつかの違いは、ここではコレクションビューにコンテナ「ul」を参照する「el」があると仮定しています。また、ソートをトリガーする方法も示していません(基本的には次のようなもの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 に答える