2016-08-04 52 views
0

Ich habe diese Tabelle, die eine Liste von Elementen aus einem Array namens Bücher hat. das heißtÄndern Sie dynamisch die Größe der Sammlung in Backbone.js von HTML Wählen Sie Formular

var books = [ 
    {"title": "Harry Potter 1", "author": "J. K. Rowling"}, 
    {"title": "Harry Potter 2", "author": "J. K. Rowling"} 
//.... More books 
] 

Ich trennte meine Ansichten in eine Ansicht für ein einzelnes Buch Zeile, die gesamte Buchliste, die in eine Tabelle gerendert wird, und auch eine Ansicht für die Auswahl-Formular.

var Book = Backbone.Model.extend({}); 

var BooksCollection = Backbone.Collection.extend({ 
    model: Book 
}); 
var Books = new BooksCollection(books); 
// 
var SelectView = Backbone.View.extend({ 
    el: ".container", 
    events: { 
     "change #num-entries": "updateBookList" 
    }, 
    initialize: function() { 
     this.render(); 
    }, 
    render: function() { 
     this.collection.models.length = $('#num-entries').val(); 
    }, 
    updateBookList: function() { 
     this.collection.models.length = $('#num-entries').val(); 
     //console.log(this.collections.models.length); 
     booksview.$el.empty(); 
     booksview.unbind(); 
     booksview.render(); 
    } 
}); 
var selectView = new SelectView({ 
    model: Book, 
    collection: Books 
}); 
// 
var BooksView = Backbone.View.extend({ 
    type: "BooksView", 
    el: "#books-table", 
    initialize: function() { 
     //this.collection.models.length = $('#num-entries').val(); 
     this.render(); 

    }, 
    render: function() { 
     this.collection.each(function(book) { 
      var bookView = new BookView({ 
       model: book 
      }); 
      bookView.render(); 
      this.$el.append(bookView.$el); 
     }, this) 
    } 
});    
var BookView = Backbone.View.extend({ 
    type: "BookView", 
    className: 'book', 
    tagName: 'tr', 
    template: _.template($("#books-template").html()), 
    events: { 
     "click .delete": "bookRemove" 
    }, 
    initialize: function() { 
     this.render(); 
    }, 
    render: function() { 
     this.$el.html(this.template(this.model.toJSON())); 
     return this; 
    }, 
    bookRemove: function(book) { 
     this.remove(); 
     this.model.trigger('destroy', this.model); 
     //Books.remove(book); 
    }, 
}); 

var booksview = new BooksView({ 
    collection: Books 
}) 

das ist in meinem html

<div class="container"> 
    <div class="form-group" id="entries-per-page"> 
     <label>Number of Entries:</label> 
     <select class="form-control" id="num-entries"> 
     <option value="10">Show 10 entries</option> 
     <option value="25" selected>Show 25 entries</option> 
     <option value="50">Show 50 entries</option> 
     <option value="100">Show 100 entries</option> 
     </select> 
    </div> 
    <table class="table table-bordered table-hover"> 
     <thead> 
      <tr class="header-names"> 
      <th class="book-category">Title</th> 
      <th class="book-category">Author</th> 
      <th class="book-category">Meta Data</th> 
      <th class="book-category">Options</th> 
      </tr> 
     </thead> 
     <tbody id="books-table"> 
      <script type="text/template" id="books-template"> 
       <td><%- title %></td> 
       <td><%- author %></td> 
       <td><span class='glyphicon glyphicon-remove delete'></span></td> 
      </script> 
     </tbody> 
    </table> 
</div> 

Derzeit meine unordentlichen Code für die ausgewählte Ansicht kann die Liste Sammlung Schrumpf machen (so meine Tabelle von 25 Einträgen bis 10 zum Beispiel geht), aber dann, wenn ich versuche, die Tabelle mehr Bücher anzuzeigen, bekomme ich einen Fehler - Uncaught TypeError: Kann die Eigenschaft 'toJSON' von undefined nicht lesen. Ich würde denken, dass die Verwendung der collection.slice-Funktion helfen sollte, aber ich kann es nicht herausfinden. Außerdem ist es schwierig, meine Funktion zum Löschen von Büchern damit zu arbeiten. Kann ich mithilfe der slice-Methode Hilfe erhalten, um die Größe meines Bucharrays oder der Büchersammlung dynamisch zu ändern, damit die Tabelle korrekt angezeigt wird?

Antwort

0

Wenn Sie das Modell-Array direkt ändern, verlieren Sie den Verweis auf Modelle, und Sie müssen das Objekt erneut zur Sammlung hinzufügen, um sie erneut anzuzeigen.

Anstatt die tatsächliche Sammlung zu ändern, sollten Sie diejenigen auswählen, die Sie in der Rendermethode benötigen. Dies ist auch auf konzeptueller Ebene sinnvoller, da die Anzahl der anzuzeigenden Einträge eher ein View-Concern als ein Data-Concern ist.

Ihre Ansicht wird nun wie folgt aussehen:

var BooksView = Backbone.View.extend({ 
    type: "BooksView", 
    el: "#books-table", 

    // Define how many books we want to display 
    booksToShow: 25, 

    initialize: function() { 
     this.render(); 
    }, 
    render: function() { 
     _.each(this.collection.slice(0, this.booksToShow), this.renderBook, this); 
    }, 
    renderBook: function(bookModel) { 
     var bookView = new BookView({ 
      model: book 
     }); 
     bookView.render(); 
     this.$el.append(bookView.$el); 
    } 
}); 

Dann updateBookList innerhalb Sie

this.collection.booksToShow = $('#num-entries').val(); 

Eine andere Sache nennen kann; Für gute Zwecke, sollten Sie daran denken, die einzelnen BookView s auch zu lösen, wenn Sie sie entfernen. Vorzugsweise durch Erstellung eines Verfahrens in BooksView zur Säuberung.