呈现视图 returns 未定义
Rendering the view returns undefined
我有一个 collection 视图,其中包含两个过滤方法和一个带有参数的渲染方法。我遇到的问题是,第一次渲染视图时 returns 我出错了。这是我的 collection:
var ResumeCollection = Backbone.Collection.extend({
url: 'http://localhost:3000',
filterActive: function () {
var active = this.where({interviewed: false});
return new ResumeCollection(active);
},
filterInterviewed: function () {
var interviewed = this.where({interviewed: true});
return new ResumeCollection(interviewed);
}
});
我的观点:
var ResumeList = Backbone.View.extend({
events { // hash array of filter events },
initialize: function () {
this.collection.fetch();
},
render: function (filtered) {
var self = this;
var data;
if (!filtered) {
data = this.collection.toArray();
} else {
data = filtered.toArray();
}
_.each(data, function (cv) {
self.$el.append((new ResumeView({model: cv})).render().$el);
});
return this;
},
showActive: function (ev) {
var filtered = this.collection.filterActive();
this.render(filtered);
},
showInterviewed: function (ev) {
var filtered = this.collection.filterInterviewed();
this.render(filtered);
},
showAll: function (ev) {
this.render(this.collection);
}
});
此视图是通过传递 collection:
在我的路由器中首次呈现的
var AppRouter = Backbone.Router.extend({
routes: {
'': 'home'
},
initialize: function () {
this.layout = new LayoutView();
}
home: function () {
this.layout.render(new ResumeList({
collection: new ResumeCollection()
}));
}
});
这是呈现所有其他视图的布局视图:
var LayoutView = Backbone.View.extend({
el: $('#outlet'),
render: function (view) {
if (this.child && this.child !== view) {
this.child.undelegateEvents();
}
this.child = view;
this.child.setElement(this.$el).render();
return this;
}
});
当我刚刷新我的页面时,出现 filtered.toArray is not a function
错误并且没有分别呈现任何内容。检查调试器中的所有内容后,我发现第一次呈现视图时,filtered
属性收到一个空的 collection,将其分配给 data
变量,它变成了一个空数组并转到 render
函数的主体,之后变为 undefined
。谜团就在这里:每当我单击绑定到我的 show*
事件的项目时,它们的行为完全符合预期并呈现 interviewed === false
或 true
或整个 [=38] 的模型=].这对我来说看起来有点神奇,我完全不知道我能用它做什么。
您在 AppRouter
上的 home
函数有错字。你多了一个分号。
home: function () {
this.layout.render(new ResumeList({
collection: new ResumeCollection();
}));
}
应该是
home: function () {
this.layout.render(new ResumeList({
collection: new ResumeCollection()
}));
}
我需要删除它才能让 JSFiddle 正常工作:https://jsfiddle.net/4gyne5ev/1/
我建议在您的 IDE 或构建过程 (http://eslint.org/)
中添加某种 linting 工具
您需要像这样将主页 url 内容添加到您的 db.json 文件
"" : [
{
'somthing': 'somthing'
}
]
经过导师的建议,我意识到问题的核心在于 fetch
方法的异步起源——当我在初始化函数中传递 this.collection.fetch
时,它在之后执行我的 render
方法,而不是在它之前,所以当第一次调用视图时,我的 render
方法没有任何东西可以呈现。因此,此修复有效:
var ResumeList = Backbone.View.extend({
initialize: function (options) {
this.collection = options.collection();
// removed .fetch() method from here
},
render: function (filtered) {
var self = this;
var data;
// and added it here:
this.collection.fetch({
success: function (collection) {
if (!filtered) {
data = collection.toArray();
} else {
data = filtered.toArray();
}
self.$el.html(self.template(collection.toJSON()));
_.each(data, function (cv) {
self.$el.append((new ResumeView({model: cv})).render().$el);
})
}
});
}
});
这完全符合我的需要。
我有一个 collection 视图,其中包含两个过滤方法和一个带有参数的渲染方法。我遇到的问题是,第一次渲染视图时 returns 我出错了。这是我的 collection:
var ResumeCollection = Backbone.Collection.extend({
url: 'http://localhost:3000',
filterActive: function () {
var active = this.where({interviewed: false});
return new ResumeCollection(active);
},
filterInterviewed: function () {
var interviewed = this.where({interviewed: true});
return new ResumeCollection(interviewed);
}
});
我的观点:
var ResumeList = Backbone.View.extend({
events { // hash array of filter events },
initialize: function () {
this.collection.fetch();
},
render: function (filtered) {
var self = this;
var data;
if (!filtered) {
data = this.collection.toArray();
} else {
data = filtered.toArray();
}
_.each(data, function (cv) {
self.$el.append((new ResumeView({model: cv})).render().$el);
});
return this;
},
showActive: function (ev) {
var filtered = this.collection.filterActive();
this.render(filtered);
},
showInterviewed: function (ev) {
var filtered = this.collection.filterInterviewed();
this.render(filtered);
},
showAll: function (ev) {
this.render(this.collection);
}
});
此视图是通过传递 collection:
在我的路由器中首次呈现的var AppRouter = Backbone.Router.extend({
routes: {
'': 'home'
},
initialize: function () {
this.layout = new LayoutView();
}
home: function () {
this.layout.render(new ResumeList({
collection: new ResumeCollection()
}));
}
});
这是呈现所有其他视图的布局视图:
var LayoutView = Backbone.View.extend({
el: $('#outlet'),
render: function (view) {
if (this.child && this.child !== view) {
this.child.undelegateEvents();
}
this.child = view;
this.child.setElement(this.$el).render();
return this;
}
});
当我刚刷新我的页面时,出现 filtered.toArray is not a function
错误并且没有分别呈现任何内容。检查调试器中的所有内容后,我发现第一次呈现视图时,filtered
属性收到一个空的 collection,将其分配给 data
变量,它变成了一个空数组并转到 render
函数的主体,之后变为 undefined
。谜团就在这里:每当我单击绑定到我的 show*
事件的项目时,它们的行为完全符合预期并呈现 interviewed === false
或 true
或整个 [=38] 的模型=].这对我来说看起来有点神奇,我完全不知道我能用它做什么。
您在 AppRouter
上的 home
函数有错字。你多了一个分号。
home: function () {
this.layout.render(new ResumeList({
collection: new ResumeCollection();
}));
}
应该是
home: function () {
this.layout.render(new ResumeList({
collection: new ResumeCollection()
}));
}
我需要删除它才能让 JSFiddle 正常工作:https://jsfiddle.net/4gyne5ev/1/
我建议在您的 IDE 或构建过程 (http://eslint.org/)
中添加某种 linting 工具您需要像这样将主页 url 内容添加到您的 db.json 文件
"" : [
{
'somthing': 'somthing'
}
]
经过导师的建议,我意识到问题的核心在于 fetch
方法的异步起源——当我在初始化函数中传递 this.collection.fetch
时,它在之后执行我的 render
方法,而不是在它之前,所以当第一次调用视图时,我的 render
方法没有任何东西可以呈现。因此,此修复有效:
var ResumeList = Backbone.View.extend({
initialize: function (options) {
this.collection = options.collection();
// removed .fetch() method from here
},
render: function (filtered) {
var self = this;
var data;
// and added it here:
this.collection.fetch({
success: function (collection) {
if (!filtered) {
data = collection.toArray();
} else {
data = filtered.toArray();
}
self.$el.html(self.template(collection.toJSON()));
_.each(data, function (cv) {
self.$el.append((new ResumeView({model: cv})).render().$el);
})
}
});
}
});
这完全符合我的需要。