构建Backbone.js项目的好方法是什么?
What's a good way to build a Backbone.js project?
我们目前正在启动我们的第一个Backbone.js项目。事实上,它是我们第一个主要的JavaScript项目,除了一些奇怪的jQuery。
无论如何,我们都在为我们的东西的架构而挣扎。整理东西的最好方法是什么?
我们已经开始把所有的东西都放在单独的文件中,分成文件夹;视图,模型,集合和路由器,然后我们把所有东西都包含在我们的index.html
中。但问题是,这使我们不得不在每个文件中检查document ready事件。这是最好的方法吗?
下面是一个例子:
这是名为PageModel
的文件,第一行似乎是错误的…
$(function(){
app.models.Page = Backbone.Model.extend({
//stuff
});
});
然后在我们的index.html
中我们有:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
<link href="assets/css/style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
var app = app || {};
app.models = app.models || {};
app.collections = app.collections || {};
app.views = app.views || {};
app.routers = app.collections || {};
app.templates = app.templates || {};
app.models.griditems = app.models.griditems || {};
app.views.griditems = app.views.griditems || {};
</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
<script src="assets/js/libs/json2.js" type="text/javascript"></script>
<script src="assets/js/libs/underscore-1.1.7.min.js" type="text/javascript"></script>
<script src="assets/js/libs/backbone-0.5.3.min.js" type="text/javascript"></script>
<script src="assets/js/models/GridItemModel.js" type="text/javascript"></script>
<script src="assets/js/models/GalleryGridItemModel.js" type="text/javascript"></script>
<script src="assets/js/models/NewsGridItemModel.js" type="text/javascript"></script>
<script src="assets/js/models/VideoGridItemModel.js" type="text/javascript"></script>
<script src="assets/js/collections/GridCollection.js" type="text/javascript"></script>
<script src="assets/js/templates/Submenu.js" type="text/javascript"></script>
<script src="assets/js/templates/GalleryGridItemTemplate.js" type="text/javascript"></script>
<script src="assets/js/views/GridView.js" type="text/javascript"></script>
<script src="assets/js/views/GridItemView.js" type="text/javascript"></script>
<script src="assets/js/views/GalleryGridItemView.js" type="text/javascript"></script>
<script src="assets/js/views/VideoGridItemView.js" type="text/javascript"></script>
<script src="assets/js/routers/Router.js" type="text/javascript"></script>
<script src="assets/js/Application.js" type="text/javascript"></script>
</head>
<body>
</body>
</html>
这是我们在主干项目中使用的结构
<!-- Libs Section -->
<script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/jquery-1.5.2.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/jquery.validate.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/jquery.maskedinput-1.3.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/jquery.mousewheel.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/jquery.scrollpane.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/fileuploader.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/modernizr.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/json2.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/underscore-min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Content/static/js/libs/backbone-min.js")"></script>
<!-- Libs Section -->
<!-- Core Section -->
<script type="text/javascript" src="@Url.Content("~/Content/static/js/config.js")"></script> <!-- Global configs -->
<script type="text/javascript" src="@Url.Content("~/Content/static/js/core.js")"></script> <!-- Core methods for easier working with views, models and collections + additional useful utils -->
<script type="text/javascript" src="@Url.Content("~/Content/static/js/app.js")"></script> <!-- Application object inherites core.js as prototype -->
<script type="text/javascript" src="@Url.Content("~/Content/static/js/renisans.js")"></script> <!-- Project Object. Creates Namespace and Extends it with project specific methods -->
<!-- Core Section -->
<!-- Routers Section -->
<script type="text/javascript" src="@Url.Content("~/Content/static/js/routers/workspace.js")"></script>
<!-- Routers Section -->
<!-- Models Section -->
<script type="text/javascript" src="@Url.Content("~/Content/static/js/models/profile.js")"></script>
...
<!-- Models Section -->
<!-- Collections Section -->
<script type="text/javascript" src="@Url.Content("~/Content/static/js/collections/messages.js")"></script>
...
<!-- Collections Section -->
<!-- Views Section -->
<script type="text/javascript" src="@Url.Content("~/Content/static/js/views/workspace.js")"></script>
...
<!-- Views Section -->
<!-- Localization Section -->
<script type="text/javascript" src="@Url.Content("~/Content/static/js/localizations/ru_RU.js")"></script>
<!-- Localization Section -->
<!-- Init Section -->
<script type="text/javascript">
$(function() {
Rens.container = $('.l-wrapper'); // Some parameters
Rens.init({
Localization: LocalizationStrings || {}, // Object with localization strings
Profile: {
// Bootstraping initial data to Profile model
}
});
});
</script>
<!-- Init Section -->
app.js的内容
var App = function() {
this.Views = {};
this.Routers = {};
this.Models = {};
this.Collections = {};
this.User = {};
this.router = null;
this.view = null;
this.baseLocation = null;
this.beforeInit = function() {};
this.afterInit = function() {};
this.init = function(initData) {
if (typeof(this.beforeInit) === 'function') {
this.beforeInit.apply(this, arguments);
}
if (this.Views.Workspace) {
this.view = new this.Views.Workspace();
}
this.baseLocation = window.location.href.replace(/[?#].*/, '') == Config.web.host;
if (this.Routers.Workspace) {
this.router = new this.Routers.Workspace(initData);
}
this.view && this.view.setListeners && this.view.setListeners();
Backbone.history.start();
if (typeof(this.afterInit) === 'function') {
this.afterInit.apply(this, arguments);
}
}.bind(this);
};
App.prototype = Core;
和renisans.js的内容
var Rens = new App();
$.extend(Rens, {
container: null,
Error: function(data) {
// Handling error
},
Localization: function(dictionary) {
return {
get: function(name) {
var argumentsList = Array.prototype.slice.call(arguments),
strings = argumentsList.slice(1),
text = this[name];
if (text && strings.length) {
$(strings).each(function(i, string) {
var reg = new RegExp('''$' + i, 'go');
text = text.replace(reg, string);
});
}
return text || 'SLB.Localization.' + name + ' not found!';
}.bind(dictionary)
}
},
formatDate: function(rawDate) {
var timestamp = /'d+/.exec(rawDate)[0],
date = Rens.DateUTC(timestamp),
months = Rens.Localization.get('months');
return {
date: date,
fullDate: [date.dd, months[date.mm], date.hh].join(' '),
shortDate: [date.dd, date.MM, date.hh].join('.')
};
},
beforeInit: function(initData) {
this.Localization = new this.Localization(initData.Localization);
}
});
也简化了models/profile.js的内容
Rens.Models.Profile = Backbone.Model.extend({
...
});
如果你正在创建一个这种形状的应用程序,我强烈建议使用动态加载你的资产,如javascript等。
你有几个选项:
- Require.js
- LABjs
- …
我自己没有LABjs的经验,但我一直在为自己在较小的项目中使用Require.js。但尚未在重大项目中使用。
这样一个系统的优点:
- 你可以使用依赖关系,你的模型或视图只会在被你代码的另一部分请求时才会被加载。
- require.js还提供了基于你指定的依赖项来最小化和聚合代码的特性。
- require.js有一些小插件用于加载文本文件(如果你使用模板系统,这可能很有用),或者一个插件来定义文件需要加载的顺序。
- 和require.js也有一个特殊的版本,用于与jquery及其模块一起工作。(但你不需要使用这个,你也可以手动加载在jquery中)
你需要包装你的模型/视图/…在模块中,require.js可以动态加载它们。上周我在stack overflow上问过这个问题…你可以在这里找到如何做到这一点的信息
我建议你阅读一下'getting started with require.js',看看你是否喜欢使用它。
因为要处理所有的模型/视图/…在开发阶段,在单独的文件中使用非常方便,但是在进入生产阶段时,不建议使用这种方法。浏览器向服务器发送的请求越少越好。
相关文章:
- 打破承诺链的好方法是什么
- 在JavaScript中拆分日期字符串的更好方法是什么
- 将jQuery.ech()方法转换为本地JavaScript抽象的最佳方法是什么
- 处理浮点错误的最佳方法是什么
- 基于窗口宽度jquery的函数的替代方法是什么
- knex:根据结果创建数组的合适方法是什么
- 以编程方式填充组合框道场 (1.8) 的最佳方法是什么?
- 使用Modernizr检测移动设备最可靠的方法是什么
- 确定var是否是javascript中的elementFinder对象的方法是什么
- 用javascript修复这个JSON对象字符串最干净的方法是什么
- 让会话值可用于JavaScript的好方法是什么
- 从AngularJs获取谷歌地图对象的正确方法是什么
- 使用ReactJS和Flux架构从服务器获取数据的正确方法是什么
- 列出没有 mysql 的元素的最佳方法是什么
- 克服错误的更优雅的方法是什么:需要对象说明符.当通过JXA通过Messages发送SMS时,参数没有对象说明符
- 使用较少代码隐藏和显示选择菜单内容的更好方法是什么?javascript
- 在 Javascript 中实现解耦代码/回调的正确方法是什么?
- 使用Javascript,获取元素的方法是什么,基于打开和关闭标记之间的文本
- 在d3.json中使用d3.csv组合多个csv文件数据输入的最佳方法是什么
- 直接在DOM事件处理程序中调用作用域函数的最短方法是什么