use*_*480 61 javascript jquery namespaces organization backbone.js
我目前正在开发一个基于backbone.js构建的大型Web应用程序,并且在组织,"僵尸"等方面遇到了很多问题.所以我决定做一个主要的代码重构.我已经编写了一堆辅助函数来处理"僵尸"; 但是,我想从一开始就为代码创建一个很好的结构/组织.我没有在大型的backbone.js组织上找到很多很棒的教程/示例,所以我从头开始,想看看我是否可以就我开始的地方得到一些意见.
我显然在全局命名空间中设置了我的代码; 但我也想保持这个命名空间相当干净.我的主要app.js使类文件本身与全局命名空间分开; 您可以使用reg()函数注册一个类(以便可以实例化它),而inst()函数可以从classes数组中实例化一个类.因此,除了3种方法之外,MyApp命名空间只有路由器,模型和视图:
var MyApp = (function () {
var classes = {
Routers: {},
Collections: {},
Models: {},
Views: {}
};
methods = {
init: function () {
MyApp.Router = MyApp.inst('Routers', 'App');
MyApp.Model = MyApp.inst('Models', 'App');
MyApp.View = MyApp.inst('Views', 'App');
Backbone.history.start();
},
reg: function (type, name, C) {
classes[type][name] = C;
},
inst: function (type, C, attrs) {
return new classes[type][C](attrs || {});
}
};
return methods;
}());
$(MyApp.init);
Run Code Online (Sandbox Code Playgroud)
在模型,集合,路由器和视图中,我像往常一样工作,但是然后需要在文件的末尾注册该类,以便可以在以后实例化它(不会使命名空间混乱):
MyApp.reg('Models', 'App', Model);
Run Code Online (Sandbox Code Playgroud)
这似乎是组织代码的不必要的方式吗?其他人是否有更好的例子来说明如何使用许多路由器,集合,模型和视图组织真正的大型项目?
nra*_*itz 32
我最近在弄称为GapVis骨干项目(这里的代码,这里呈现的内容).我不知道它是否"非常大",但它是大而且相对复杂 - 24个视图类,5个路由器等等.虽然我不知道我的所有方法都是相关.你可以在我的主app.js文件中看到我的一些想法.一些关键的架构选择:
我有一个State包含所有当前状态信息的单例模型 - 当前视图,我们正在查看的模型ID等等.每个需要修改应用程序状态的视图都通过设置属性State以及需要响应的每个视图来实现到州听这个模型的事件.对于修改状态和更新的视图尤其如此 - UI事件处理程序events永远不会重新呈现视图,而是通过将呈现函数绑定到状态来完成.这种模式确实有助于保持视图彼此分离 - 视图从不在另一个视图上调用方法.
我的路由器被视为专用视图 - 它们通过更新状态来响应UI事件(即键入URL),并通过更新UI(即更改URL)来响应状态更改.
我做了几件类似于你提议的事情.我的命名空间有一个init类似于你的命名空间,以及一个settings常量对象.但我也将大部分模型和视图类放在命名空间中,因为我需要在多个文件中引用它们.
我为我的路由器使用了一个注册系统,并考虑了一个用于我的视图,这是保持"主"类(AppRouter和AppView)不必知道每个视图的好方法.AppView但是,在这种情况下,事实证明,子视图的顺序非常重要,因此我最终对这些类进行了硬编码.
我几乎不会说这是做事的"正确"方式,但它对我有用.我希望这很有帮助 - 我也很难找到使用Backbone的大型项目的可见源代码示例,并且随着我的进展不得不解决大部分问题.
小智 13
这2个资源帮助我在坚实的地下室设置我的骨干应用程序:
命名空间类似于你正在做的事情(至少对于类部分而言),我的所有模型,视图和控制器都是这样的:
意见/ blocks.js:
(function(cn){
cn.classes.views.blocks = cn.classes.views.base.extend({
events: {},
blocksTemplate: cn.helpers.loadTemplate('tmpl_page_blocks'),
initialize: function(){
},
render: function(){
$(this.el).html(this.blocksTemplate());
},
registerEvents: function(){},
unregisterEvents: function(){}
});
})(companyname);
Run Code Online (Sandbox Code Playgroud)
我的JavaScript命名空间看起来像这样,尽管我每次构建新应用程序时都会改进它:
companyname:{
$: function(){}, <== Shortcut reference to document.getElementById
appView: {}, <== Reference to instantiated AppView class.
classes = { <== Namespace for all custom Backbone classes.
views : {},
models : {},
collections: {},
controllers : {},
Router: null
},
models: {}, <== Instantiated models.
controllers: {}, <== Instantiated controllers.
router: {}, <== Instantiated routers.
helpers: {}, <== Reusable helper platform methods.
currentView: {}, <== A reference to the current view so that we can destroy it.
init: function(){} <== Bootstrap code, starts the app.
}
Run Code Online (Sandbox Code Playgroud)
我希望我的所有观点都有,我把它放在基本视图中.我的控制器将调用registerEvents它创建的任何新视图(渲染后)和unregisterEvents视图,然后再杀死它.并非所有视图都有这两个额外的方法,所以它首先检查是否存在.
不要忘记所有视图都带有this.el.remove();内置.这不仅会杀死视图容器元素,还会取消绑定附加到它的所有事件.根据您通过控制器创建视图的方式,您实际上可能不想杀死该元素并执行this.el.unbind()而不是取消绑定所有事件.
事实上,以不同的方式有不同方式的优点和缺点.最重要的是找到一种合适的文件组织方式.以下是我目前正在进行的项目的组织.这种方式的重点是将相同的模块相关文件放在一个文件夹中.例如:people模块,这个模块的所有文件都放在modules/base/people目录下.更新和维护这个模块后,只需要关注此目录中的文件就行了,不会影响目录外的文件,并提高了可维护性.
我希望我的回答可以给你一些帮助,我希望你有一些宝贵的建议.
