Javascript 如何在列表和项目视图中呈现主干集合?
我在一个联系人栏上工作,它在html列表中呈现用户的所有联系人 我所拥有的:Javascript 如何在列表和项目视图中呈现主干集合?,javascript,backbone.js,Javascript,Backbone.js,我在一个联系人栏上工作,它在html列表中呈现用户的所有联系人 我所拥有的: UserModel-这是一个简单的主干。带有用户名和电子邮件的模型 UserCollection-用作联系人列表 ContactsView-这是ul联系人列表 ContactView-这是渲染为li的单个联系人模型 我目前正在绞尽脑汁研究一种解决方案,即如何(以及在何处)获取我的UserCollection,以及如何将单个模型向下传递到单个ContactView项 具体障碍包括: 我应该在哪里提取、存储UserColl
// 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 });
联系人视图:
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;
});
有人能帮我克服四个障碍吗
欢迎提供好的示例链接。我将我的代码风格定位在todos列表中,不幸的是,todos列表没有那么高级
更新代码:
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;
重置是否会触发此.render两次?首先:为什么要获取视图?主干视图没有获取方法 1获取UserCollection的正确位置应在视图的initialize方法中: 现在,您可以在需要时准确地获取联系人。下一步是呈现集合 2绑定到重置事件会使loadContacts方法过时,我们可以在render函数中执行此操作: 现在,您可以在render方法中呈现联系人列表,应该在该方法中完成 3 ContactView实际上看起来不错。 只需使该项在initialize方法中呈现自己,就不必在ContactsView的呈现方法中进行无用的调用,也不必将代码弄得乱七八糟。也都在这里
initialize: function() { // ContactView
_.bindAll(this, 'render', 'otherMethodName', ...);
...
this.render(); // Render in the end of initialize
}
我不知道你在问什么,但我认为最好的方法是不要使用成功回调。无论何时对集合和模型执行操作,它们都会触发事件,因此利用它们比成功回调更健壮、更可靠。Christophe Coenraets的是这种listview listitemview排列的一个很好的例子
希望这有帮助
更新:添加了u.bindAlls以修复事件绑定渲染调用中的此问题 注意:所有代码都经过简化,没有经过测试
当我像您一样定义了所有的元素结构并实现了所有的模型、集合和视图之后,我实现了一个加载程序,它负责触发抓取和渲染操作
首先,我需要从外部公开类定义,如下所示:
// App.js
var App = {}
// ContactsCollection.js
$(function(){
var App.ContactsCollection = Backbone.Collection.extend({ ... });
});
// ContactsView.js
$(function(){
var App.ContactsView = Backbone.View.extend({ ... });
});
// and so on...
然后我实现了我称之为加载器的东西:
您必须做的另一个更改是配置ContactsView
,以响应App.contactsCollection
中的更改,因为fetch()
是异步的,所以在尚未加载集合时,您可以调用render()
,因此,您必须告诉CollectionView在集合准备就绪时自行渲染它:
var ContactsView = Backbone.View.extend({
initialize: function( opts ){
this.collection.on( 'reset', this.addAll, this );
this.collection.on( 'add', this.addOne, this );
// ... same with 'remove'
},
addOne: function( model ){
var view = new App.ContactView({ model: contact });
this.$el.append( view.render().el );
},
addAll: function(){
this.collection.each( $.proxy( this.addOne, this ) );
}
});
您必须按照正确的顺序要求js文件:
- 外部访问您的收藏,以防您需要从其他地方访问它
- 使用的
的外部控制更适合于解耦和测试CollectionView.el
- CollectionView将自动响应集合中的更改
注意:如果您使用
路由器
可以将AppLoad.js
逻辑移动到那里。您好,谢谢您的帮助。这确实让我更清楚:)似乎有两个错误。1.)此。$el未定义2.)渲染将被调用两次。我用新的codeundefined更新了最初的帖子,它是由javascript作用域引起的,这导致它并不总是预期的那样。这可以通过下划线的bindAll-函数修复。我更新了我的回答,当然,当您将渲染绑定到事件时,您应该删除应用程序入口点代码中的渲染调用:this.$el.append(view.render().el)代码>->此.el.append(view.el)代码>在循环中附加DOM节点可能会对性能造成影响,我们可以渲染每个视图,然后一起推入DOM。如果我们已经像这里提到的那样引导了模型,该如何处理?嗨,这也是一个有趣的方法。稍后我们将仔细查看
initialize: function() { // ContactView
_.bindAll(this, 'render', 'otherMethodName', ...);
...
this.render(); // Render in the end of initialize
}
// App.js
var App = {}
// ContactsCollection.js
$(function(){
var App.ContactsCollection = Backbone.Collection.extend({ ... });
});
// ContactsView.js
$(function(){
var App.ContactsView = Backbone.View.extend({ ... });
});
// and so on...
// AppLoad.js
$(function(){
// instantiate the collection
var App.contactsCollection = new App.ContactsCollection();
// instantiate the CollectionView and assign the collection to it
var App.contactsView = new App.ContactsView({
el: "div.contacts-body ul",
collection: App.contactsCollection
});
// fetch the collection the contactsView will
// render the content authomatically
App.contactsCollection.fetch();
});
var ContactsView = Backbone.View.extend({
initialize: function( opts ){
this.collection.on( 'reset', this.addAll, this );
this.collection.on( 'add', this.addOne, this );
// ... same with 'remove'
},
addOne: function( model ){
var view = new App.ContactView({ model: contact });
this.$el.append( view.render().el );
},
addAll: function(){
this.collection.each( $.proxy( this.addOne, this ) );
}
});