Wie kann ich das Rendern einer Backbone-Sammlung in einer Liste und Element-Anzeigen?
Arbeite ich an einer Kontakt-bar, die macht alle Kontakte eines Benutzers in einer html-Liste.
Was ich habe:
- UserModel - Dies ist eine einfache Backbone.Modell mit Benutzernamen und E-Mail
- UserCollection - Dies ist der Kontakt-Liste
- ContactsView - das ist der ul-Kontaktliste
- ContactView - Dies ist ein single-Kontakt-Modell gerendert li
Ich bin derzeit bricht meinen Kopf über eine Lösung, wie (und wo) kann ich Holen meine UserCollection und wie gebe ich den einzelnen Modellen bis hin zu einzelnen ContactView Element.
Spezifischen Hürden sind:
- Wo sollte ich Holen, speichern Sie die UserCollection
- Wie kann ich machen das Kontakt-Liste
- Wie kann ich machen das Kontakt-Elemente
- Wie kann ich verhindern, dass fetch({ success: callback }), aus brechenden meine code-Struktur
Mein aktuelle code ist:
Eingang Punkt:
//create a new instance of the contact list view
var view = new ContactsView();
//insert the rendered element of the contact list view in to the dom
$('div.contacts-body').html(view.render().el);
view.fetch({ success: view.loadContacts });
ContactsView:
define(
['jquery', 'underscore', 'backbone', 'text!templates/conversations/contacts.html', 'collections/users', 'views/conversations/contact'],
function($, _, Backbone, ContactsTemplate, UserCollection, ContactView) {
var ContactsView = Backbone.View.extend({
tagName: "ul",
className: "contacts unstyled",
attributes: "",
//I am feeling uneasy hardcoding the collection into the view
initialize: function() {
this.collection = new UserCollection();
},
//this renders our contact list
//we don't need any template because we just have <ul class="contacts"></ul>
render: function() {
this.$el.html();
return this;
},
//this should render the contact list
//really crappy and unflexible
loadContacts: function() {
this.collection.each(function(contact) {
//create a new contact item, insert the model
var view = new ContactView({ model: contact });
//append it to our list
this.$el.append(view.render().el);
});
}
});
return ContactsView;
});
ContactView
define(
['jquery', 'underscore', 'backbone', 'text!templates/conversations/contact.html'],
function($, _, Backbone, ContactTemplate) {
var ContactView = Backbone.View.extend({
tagName: "li",
className: "contact",
attributes: "",
template:_.template(ContactTemplate),
initialize: function() {
this.model.bind('change', this.render, this);
this.model.bind('destroy', this.remove, this);
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
return ContactView;
});
Könnte jemand mir helfen, über meine vier Hürden.
Gutes Beispiel links sind willkommen. Ich orientierte meinen code-Stil im todos-Liste leider todos-Liste ist nicht, dass fortgeschrittene...
AKTUALISIERTEN CODE:
define(
['jquery', 'underscore', 'backbone', 'text!templates/conversations/contacts.html', 'collections/users', 'views/conversations/contact'],
function($, _, Backbone, ContactsTemplate, UserCollection, ContactView) {
var ContactsView = Backbone.View.extend({
tagName: "ul",
className: "contacts unstyled",
attributes: "",
events: {
},
initialize: function() {
this.collection = new UserCollection();
this.collection.on('reset', this.render);
this.collection.fetch();
},
render: function() {
//in chromium console
console.log(this.el); //first: html, second: undefined
console.log(this.$el); //first: html in array, second: undefined
this.$el.empty(); //error on the called that this.$el is undefined
this.collection.each(function(contact) {
var view = new ContactView({ model: contact });
this.$el.append(view.el);
}.bind(this));
return this;
}
});
return ContactsView;
Kann es sein, dass der reset ausgelöst wird dieser.render zweimal?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Zunächst: warum Holen Sie die Aussicht? Rückgrat Ansichten nicht über ein fetch-Methode..
1 Der richtigen Stelle zu Holen Ihr UserCollection wäre innerhalb der Ansicht der initialize-Methode:
Nun Holen Sie sich die Kontakte genau dann, wenn Sie Sie benötigen. Der nächste Schritt ist, um zu machen die Sammlung.
2-Bindung an das reset-Ereignis ist, Ihre loadContacts Methode veraltet und wir können dies in der render-Funktion:
Nun machen Sie Ihre Kontaktliste innerhalb der render-Methode, wo es getan werden sollte.
3 Die ContactView sieht eigentlich gut aus.
Einfach machen, das Objekt zu Rendern selbst in der initialize-Methode, so dass Sie nicht haben, um unnütze Aufrufe in der ContactsView die render-Methode und Krempel in deinem code. Auch bindAll auch hier.
Ich habe keine Ahnung, was Sie Fragen hier, aber ich denke, der beste Weg ist nicht zu verwenden success-callbacks. Die Kollektionen und Modelle, die Ereignisse auslösen, wenn etwas getan wird, um Sie, so Tippen Sie auf Sie ist sehr viel robuster und zuverlässiger ist als der Erfolg von Rückrufen. Schauen Sie sich den Katalog der Veranstaltungen, um mehr zu erfahren. Die Weinkeller tutorial von Christophe Coenraets ist ein hervorragendes Beispiel für diese Art von listview-listitemview Anordnung.
Hoffe, das hilft!
UPDATE: es wurde _.bindAlls um das problem zu beheben mit diesem in einem Ereignis gebunden render-Aufruf. Einige Infos über diese Bindung.
this.$el.append(view.render().el);
->this.$el.append(view.el);
HINWEIS: alle der code ist vereinfacht und nicht getestet
Wenn ich alle Elemente der Struktur definiert ist, da Sie haben, mit all den Models, Collections und Views implementiert, dann implementiere ich eine Loader was in charge of-trigger, die das abrufen und Rendern Aktionen.
Zunächst muss ich machen, dass das Klassen-definition von außen so etwas wie dieses:
Dann implementiere ich das, was ich die Loader:
Anderen änderungen, die Sie tun müssen ist, konfigurieren Sie die
ContactsView
in einer Weise, die reagieren auf die Veränderungen in derApp.contactsCollection
weil diefetch()
ist asynchron aufrufen können Sierender()
wenn die Sammlung noch nicht geladen, so muss man sagen, der CollectionView zu machen, es selbst, wenn die Sammlung fertig ist:Müssen Sie erfordern deine js-Dateien in der richtigen Reihenfolge:
Mit diesem system erhalten Sie:
CollectionView.el
mit ist besser für Entkopplung und testen.Hinweis: Wenn Sie
Router
können Sie dieAppLoad.js
Logik gibt.