Extenting BackBone.js网站应用程序-呈现新视图的问题
我目前正在尝试使用backbone.js提高速度,我认为最好的方法是进入在线教程和文档。在线教程和示例应用程序都非常优秀,但为了根据知识进行构建,我正在尝试构建一个示例网站CRUD应用程序。对于这个示例,我试图做的基本上是合并两个当前的在线示例/教程。试图更好地理解如何使用多个模型、集合和视图 不幸的是我被卡住了。。。我为冗长的解释道歉,但作为一个新手,我正试图尽可能最好地解释这个问题 我的网站应用程序示例基于以下教程: 在线查看示例: 我能够按照这个教程,并有一个网站的工作版本。现在,我希望扩展应用程序以包含更多适合应用程序(backbone.js)结构的页面。如果查看教程,您会注意到有一个“关于”页面,它只是将静态html模板加载到应用程序中。我想做的是添加一个显示联系人管理器的新页面。联系人管理器将从以下教程中删除: 请注意:为了简单起见,我现在只使用教程的第1部分 好的,现在来解释我的问题所在。。。首先,我将概述我所做的工作。在应用程序上,我在headerView中添加了一个名为Directory的新链接。在main.js页面(origianl的示例:)中,我添加了如下代码:Extenting BackBone.js网站应用程序-呈现新视图的问题,backbone.js,Backbone.js,我目前正在尝试使用backbone.js提高速度,我认为最好的方法是进入在线教程和文档。在线教程和示例应用程序都非常优秀,但为了根据知识进行构建,我正在尝试构建一个示例网站CRUD应用程序。对于这个示例,我试图做的基本上是合并两个当前的在线示例/教程。试图更好地理解如何使用多个模型、集合和视图 不幸的是我被卡住了。。。我为冗长的解释道歉,但作为一个新手,我正试图尽可能最好地解释这个问题 我的网站应用程序示例基于以下教程: 在线查看示例: 我能够按照这个教程,并有一个网站的工作版本。现在,我希
var AppRouter = Backbone.Router.extend({
routes: {
"" : "list",
"wines/page/:page" : "list",
"wines/add" : "addWine",
"wines/:id" : "wineDetails",
"about" : "about",
"directory" : "directory"
},
initialize: function () {
this.headerView = new HeaderView();
$('.header').html(this.headerView.el);
},
list: function(page) {
var p = page ? parseInt(page, 10) : 1;
var wineList = new WineCollection();
wineList.fetch({success: function(){
$("#content").html(new WineListView({model: wineList, page: p}).el);
}});
this.headerView.selectMenuItem('home-menu');
},
wineDetails: function (id) {
var wine = new Wine({id: id});
wine.fetch({success: function(){
$("#content").html(new WineView({model: wine}).el);
}});
this.headerView.selectMenuItem();
},
addWine: function() {
var wine = new Wine();
$('#content').html(new WineView({model: wine}).el);
this.headerView.selectMenuItem('add-menu');
},
about: function () {
if (!this.aboutView) {
this.aboutView = new AboutView();
}
$('#content').html(this.aboutView.el);
this.headerView.selectMenuItem('about-menu');
},
directory: function () {
if (!this.directoryView) {
this.directorytView = new DirectoryView();
}
$('#content').html(this.directoryView.el);
this.headerView.selectMenuItem('directory-menu');
}
//demo data
window.contacts = [
{ name: "Contact 1", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
{ name: "Contact 2", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
{ name: "Contact 3", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "friend" },
{ name: "Contact 4", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "colleague" },
{ name: "Contact 5", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
{ name: "Contact 6", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "colleague" },
{ name: "Contact 7", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "friend" },
{ name: "Contact 8", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" }
];
//define product model
window.Contact = Backbone.Model.extend({
defaults: {
photo: "/img/placeholder.png"
}
});
//define directory collection
window.Directory = Backbone.Collection.extend({
model: Contact
});
//define individual contact view
window.ContactView = Backbone.View.extend({
tagName: "article",
className: "contact-container",
template: $("#contactTemplate").html(),
render: function () {
var tmpl = _.template(this.template);
$(this.el).html(tmpl(this.model.toJSON()));
//alert('this model: ' + this.model.toJSON().name);
return this;
}
});
//define master view
window.DirectoryView = Backbone.View.extend({
el: $("#contacts"),
initialize: function () {
this.collection = new Directory(contacts);
this.render();
},
render: function () {
var that = this;
_.each(this.collection.models, function (item) {
that.renderContact(item);
}, this);
},
renderContact: function (item) {
var contactView = new ContactView({
model: item
});
this.$el.append(contactView.render().el);
}
});
}))
加载模板(['HeaderView','WineView','WineListItemView','AboutView','DirectoryView',function()){
app=新批准人();
Backbone.history.start();
});
现在,对于目录(联系人管理器)页面,为了便于解释,我已经按照教程将模型视图和集合保留在单个.js文件上-当然,我希望在文件工作后将其分离(分为模型和视图)。根据本教程,联系人管理器(目录)的代码如下:
var AppRouter = Backbone.Router.extend({
routes: {
"" : "list",
"wines/page/:page" : "list",
"wines/add" : "addWine",
"wines/:id" : "wineDetails",
"about" : "about",
"directory" : "directory"
},
initialize: function () {
this.headerView = new HeaderView();
$('.header').html(this.headerView.el);
},
list: function(page) {
var p = page ? parseInt(page, 10) : 1;
var wineList = new WineCollection();
wineList.fetch({success: function(){
$("#content").html(new WineListView({model: wineList, page: p}).el);
}});
this.headerView.selectMenuItem('home-menu');
},
wineDetails: function (id) {
var wine = new Wine({id: id});
wine.fetch({success: function(){
$("#content").html(new WineView({model: wine}).el);
}});
this.headerView.selectMenuItem();
},
addWine: function() {
var wine = new Wine();
$('#content').html(new WineView({model: wine}).el);
this.headerView.selectMenuItem('add-menu');
},
about: function () {
if (!this.aboutView) {
this.aboutView = new AboutView();
}
$('#content').html(this.aboutView.el);
this.headerView.selectMenuItem('about-menu');
},
directory: function () {
if (!this.directoryView) {
this.directorytView = new DirectoryView();
}
$('#content').html(this.directoryView.el);
this.headerView.selectMenuItem('directory-menu');
}
//demo data
window.contacts = [
{ name: "Contact 1", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
{ name: "Contact 2", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
{ name: "Contact 3", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "friend" },
{ name: "Contact 4", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "colleague" },
{ name: "Contact 5", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" },
{ name: "Contact 6", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "colleague" },
{ name: "Contact 7", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "friend" },
{ name: "Contact 8", address: "1, a street, a town, a city, AB12 3CD", tel: "0123456789", email: "anemail@me.com", type: "family" }
];
//define product model
window.Contact = Backbone.Model.extend({
defaults: {
photo: "/img/placeholder.png"
}
});
//define directory collection
window.Directory = Backbone.Collection.extend({
model: Contact
});
//define individual contact view
window.ContactView = Backbone.View.extend({
tagName: "article",
className: "contact-container",
template: $("#contactTemplate").html(),
render: function () {
var tmpl = _.template(this.template);
$(this.el).html(tmpl(this.model.toJSON()));
//alert('this model: ' + this.model.toJSON().name);
return this;
}
});
//define master view
window.DirectoryView = Backbone.View.extend({
el: $("#contacts"),
initialize: function () {
this.collection = new Directory(contacts);
this.render();
},
render: function () {
var that = this;
_.each(this.collection.models, function (item) {
that.renderContact(item);
}, this);
},
renderContact: function (item) {
var contactView = new ContactView({
model: item
});
this.$el.append(contactView.render().el);
}
});
我所做的更改只是删除“var”并替换为“window”,以适应应用程序的现有结构。例如:
var DirectoryView=Backbone.View.extend({
变成:
window.DirectoryView=Backbone.View.extend({
现在我要讨论的问题是,我能够获得输出(呈现)html代码以显示模板的代码
我认为问题在于
//define individual contact view
window.ContactView = Backbone.View.extend({
tagName: "article",
className: "contact-container",
template: $("#contactTemplate").html(),
render: function () {
var tmpl = _.template(this.template);
$(this.el).html(tmpl(this.model.toJSON()));
alert('this model: ' + this.model.toJSON().name);
return this;
}
});
现在我知道数据被正确解析,因为“警报”正确输出了名称。我遇到的问题是以下代码行:
var tmpl = _.template(this.template);
正在引发以下错误:“UncaughtTypeError:无法调用null的“replace”方法”
我对如何解决这个问题一无所知:(
DirectoryView.html模板代码为:
<div class="row">
<div class="span12">
<div id="contact"></div>
<script id="contactTemplate" type="text/template">
<img src="<%= photo %>" alt="<%= name %>" />
<h1><%= name %><span><%= type %></span></h1>
<div><%= address %></div>
<dl>
<dt>Tel:</dt><dd><%= tel %></dd>
<dt>Email:</dt><dd><a href="mailto:<%= email %>"><%= email %></a></dd>
</dl>
</script>
</div>
“alt=”“/>
电话:
电邮:
我希望我提供了足够的信息。如果需要更多信息,请告诉我
感谢您的关注:)
杰克
无法调用null的方法“replace”
这意味着在\uuu.template
方法中,您正试图调用replace
来替换空值,可能是字符串。undescore方法如下所示(从)
因此变量text
必须为null。在代码中text
是this.template
,因此在初始化时必须为null
您确定在扩展
视图
以创建ContactView
时,#contactTemplate
元素已加载到DOM中吗?问题一定存在。请尝试在控制台上记录this.template以查看它是否真的为空。如果要确保在运行任何javascript之前加载DOM,请将它们包装到jQu中ery。据我所知,它可以工作,可能是一个未完全初始化的模型,请尝试使用模板中使用的所有变量填充Contact.defaults。