2016-10-20 5 views
1

Ich habe eine , die eine Sammlung rendert und filtert es per Mausklick. Ich muss Klasse active zu der Schaltfläche hinzufügen, auf die ich klicke, aber das Problem ist, dass Schaltflächen der Teil dieser Ansicht sind, und wenn ich versuche, addClass oder toggleClass es nur wieder mit Standardklasse rendert. Hier ist meine Ansicht:Toggle-Klasse bei Mausklick Ereignis

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

Aber wie ich schon gesagt habe, die Klasse muss ich umgeschaltet wird oder nur für einen Moment gegeben, dann wird die Ansicht gerendert wieder und es wird auf die Standardklasse. Gibt es einen Weg, damit umzugehen?

Antwort

1

Ich vereinfachte das Rendering und fügte einige Optimierungen hinzu.

Da wir keine Vorlage haben, habe ich es Optimierung aktivieren:

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

Zusätzliche Informationen::

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

    Dann wird Ihr Listenansicht so sein könnte

  • Managing Views and Memory Leaks
  • Underscore's each (das dritte Argument bemerken)
  • Versuchen callback hell zu vermeiden, stellen Sie die Rückrufe wiederverwendbar (wie renderItem)
0

Ich habe den Schnipsel bearbeitet können Sie dies versuchen.

Bitte beachten Sie: Ich habe Checkbox-Element anstelle von Button genommen.

+0

'toggleElement' ist uncessary seit' dies. $ El.find ('# aktiv') 'ist hartcodiert macht 'toggleActive' zu ​​kompliziert, um jQuery zu verwenden. –

Verwandte Themen