2016-10-20 24 views
1

私はBackbone.Viewを持っています。これはコレクションをレンダリングし、マウスクリックでフィルタリングします。クリックするボタンにクラスactiveを追加する必要がありますが、ボタンはこのビューの一部であり、いつでもaddClassまたはtoggleClassにしようとすると、デフォルトのクラスで再びレンダリングされます。マウスクリックイベントでクラスを切り替えます

var ResumeList = Backbone.View.extend({ 
    events: { 
     'click #active': 'showActive', 
     'click #passed': 'showPassed' 
    }, 
    initialize: function() { 
     this.collection = new ResumeCollection(); 
    }, 

    render: function (filtered) { 
     var self = this; 
     var data; 
     if (!filtered) { 
      data = this.collection.toArray(); 
     } else { 
      data = filtered.toArray(); 
     } 
     this.$el.html(this.template({ collection: this.collection.toJSON() }); 

     _.each(data, function (cv) { 
      self.$el.append((new ResumeView({model: cv})).render().$el); 
     }); 
     return this;  
    }, 

    showActive: function() { 
     this.$('#active').toggleClass('active'); 
     // a function that returns a new filtered collection 
     var filtered = this.collection.filterActive(); 
     this.render(filtered); 
    } 
}); 

しかし、私はすでに言ったように、私は必要なクラスは、ビューが再描画され、クラスをデフォルトに設定されている、ちょっと切り替えまたは追加されます。ここに私の見解です。これを処理する方法はありますか?

答えて

1

私はレンダリングを単純化し、いくつかの最適化を追加しました。

私たちはあなたのテンプレートを持っていないので、私は最適化を有効にするために、それを変更:

<button id="active" type="button">Active</button> 
<button id="passed" type="button">Passed</button> 
<div class="list"></div> 

その後、あなたのリストビューは、このようなことができます:

var ResumeList = Backbone.View.extend({ 
    events: { 
     'click #active': 'showActive', 
     'click #passed': 'showPassed' 
    }, 
    initialize: function() { 
     this.childViews = []; 
     this.collection = new ResumeCollection(); 
    }, 

    render: function() { 
     this.$el.html(this.template()); 
     // cache the jQuery element once 
     this.elem = { 
      $list: this.$('.list'), 
      $active: this.$('#active'), 
      $passed: this.$('#passed') 
     }; 
     this.renderList(); // default list rendering 
     return this; 
    }, 

    renderList: function(collection) { 
     this.elem.$list.empty(); 
     this.removeChildren(); 
     collection = collection || this.collection.models; 

     // Underscore's 'each' has a argument for the context. 
     _.each(collection, this.renderItem, this); 
    }, 
    renderItem: function(model) { 
     var view = new ResumeView({ model: model }); 
     this.childViews.push(view); 
     this.elem.$list.append(view.render().el); 
    }, 

    showActive: function() { 
     this.elem.$active.toggleClass('active'); 

     var filtered = this.collection.filterActive(); 
     this.renderList(filtered); 
    }, 

    /** 
    * Gracefully call remove for each child view. 
    * This is to avoid memory leaks with listeners. 
    */ 
    removeChildren: function() { 
     var view; 
     while ((view = this.childViews.pop())) { 
      view.remove(); 
     } 
    }, 
}); 

追加情報:

0

私はあなたがこれを試すことができますスニペットを編集しました。

var ResumeList = Backbone.View.extend({ 
      events: { 
       'click #active': 'filterActive', 
       'click #passed': 'showPassed' 
      }, 

      toggleElement: undefined, 

      initialize: function() { 
       this.collection = new ResumeCollection(); 
      }, 

      render: function (filtered) { 
       var self = this; 
       var data; 
       if (!filtered) { 
        data = this.collection.toArray(); 
       } else { 
        data = filtered.toArray(); 
       } 
       this.$el.html(this.template({ collection: this.collection.toJSON() }); 

       _.each(data, function (cv) { 
        self.$el.append((new ResumeView({model: cv})).render().$el); 
       }); 
       return this;  
      }, 

      filterActive: function (evt) { 

       this.toggleElement = this.$el.find(evt.currentTarget); 
       // a function that returns a new filtered collection 
       var filtered = this.collection.filterActive(); 
       this.render(filtered); 
       this.toggleActive(); 
      }, 

      toggleActive: function() { 

       if(this.toggleElement.is(':checked')) { 
        this.$el.find('#active').addClass('active'); 
       } else { 
        this.$el.find('#active').removeClass('active'); 
       } 
      } 
     }); 

注意:ボタンの代わりにチェックボックスの要素を使用しました。

+0

'toggleElement'が。$ el.find( '#アクティブが')'ハードコードされ、この 'ので、uncessaryです'toggleActive'をjQueryを使うための複雑すぎる方法にしています。 –

関連する問題