我目前正在尝试使用backbone.js,我认为最好的方法是进入在线教程和文档。在线教程和示例应用程序非常好,但为了通过知识构建,我正在尝试构建我自己的示例网站 CRUD 应用程序。对于示例,基本上我想要做的是合并两个当前的在线示例/教程。试图更好地理解使用多个模型、集合和视图。
不幸的是我被卡住了......我为冗长的解释道歉,但作为一个新手,我试图尽可能地解释这个问题......
我的网站应用程序示例基于以下教程:
https://github.com/ccoenraets/backbone-cellar/tree/master/bootstrap
查看在线示例:
http://coenraets.org/backbone-cellar/bootstrap/
我能够遵循本教程并拥有该站点的工作版本。现在我希望扩展应用程序以包含更多适合应用程序(backbone.js)结构的页面。如果您查看教程,您会注意到有一个“关于”页面,它只是将静态 html 模板加载到应用程序中。我想做的是添加一个显示联系人管理器的新页面。联系人管理器被剥夺了以下教程:
http://net.tutsplus.com/tutorials/javascript-ajax/build-a-contacts-manager-using-backbone-js-part-1/
请注意:为简单起见,此时我仅使用本教程的第 1 部分。
好的,现在解释一下我遇到的问题......首先,我将概述我所做的事情。在应用程序上,我在 headerView 中添加了一个名为 Directory 的新链接。在 main.js 页面(原始示例:https ://github.com/ccoenraets/backbone-cellar/blob/master/bootstrap/js/main.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');
}
});
utils.loadTemplate(['HeaderView', 'WineView', 'WineListItemView', 'AboutView', 'DirectoryView'], function() { app = new AppRouter(); Backbone.history.start(); });
现在对于目录(联系人管理器)页面,为了解释起见,我按照教程将模型视图和集合留在了单个 .js 文件中 - 我当然希望将文件分开(分成模型和视图) 一旦我让它工作。根据教程,联系人管理器(目录)的代码如下:
//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);
正在引发以下错误:“未捕获的 TypeError:无法调用 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>
我希望我提供了足够的信息。如果需要更多信息,请告诉我。
谢谢你看:)
杰克