本文不讨论Backbone(一下简称BN)的优缺点,已经认为你在使用BN或者想使用BN。
这是我在项目中的使用经验拿出来和大家分享讨论:
(为了保密,以下的代码不是项目中的真是代码,单纯为了举例说明)
1. 项目组织结构。
前端使用的ROR,后端是纯RESTFul接口。
目录:
MyProject 根路径
public 公共资源路径
css 层叠样式表库
img 图片库
js JavaScript库
app.js 实例的初始化文件,项目入口文件
models.js 原型类库
views.js 视图类库
collections.js 集合类库
router.js 路由类库
common.js 公共JS库
views 视图实例库
system 系统管理模块
users.js 用户管理视图
roles.js 角色管理视图
chart 展示图管理模块
pies.js 饼图管理模块
template 模版库
system ...
users.html 用户管理使用模版
roles.html 角色管理使用模版
chart ...
pies.html 饼图展示模版
common.html 公共展示模版
上面仅展示了JSMVC相关的目录结构。蓝色为目录,绿色是文件。
其中视图的js和模版分别进行了模块化,创建了对应的目录结构(system和chart)
2. Backbone 本身没有模块化,这是我们不太爽,因为如果你对用用户和角色都有CRUD的操作,你为了避免命名冲突就要使用addUser、addRole、editUser、editRole...这当然不爽了,那么我们自己实现模块化。
对Model模块化:
// public/js/models.js
var company = (function(c){
c.model.system = (function(s){
s.User = Backbone.Model.extend();
s.Role = Backbone.Model.extend();
return s;
})(c.model.system || {})
return c;
})(company || {});
对Collection模块化:
// public/js/collections.js
var company = (function(c){
c.coll.system = (function(s){
s.Users = Backbone.Collection.extend({
url: '/users',
model: c.system.User
});
s.Roles = Backbone.Collection.extend({
url: '/roles',
model: c.system.Role
});
return s;
})(c.coll.system || {})
return c;
})(company || {});
对View类的模块化:
如果是列表视图一般不用创建多个,因为都是在页面的同一地方进行展示,所以使用统一的视图,然后覆盖其render方法即可。
对页面的模块化:
// public/js/views/system/users.js
var company = (function(c){
c.view.system = c.view.system || {}
c.view.system.user = {
list: function(){};
add: function(){};
edit: function(id){};
del: function(ids){};
};
return c;
})(company || {});
// public/js/views/system/roles.js
var company = (function(c){
c.view.system = c.view.system || {}
c.view.system.role = {
list: function(){};
add: function(){};
edit: function(id){};
del: function(ids){};
};
return c;
})(company || {});
对Router的模块化:
// public/js/router.js
var company = (function(c){
c.router = (function(r){
r.Base = Backbone.Router.extend({
routes: {
"system": "changeToSystem",
"chart": "changeToChart"
},
changeToSystem: function(){},
changeToChart: function(){}
});
r.base = new r.Base();
return r;
})(c.router || {})
var SystemRouterAndSystemView = (function(rs, vs){
rs.User = Backbone.Router.extend({
routes: {
"system/users": "index",
"system/users/add": "add",
"system/users/edit/:id": "edit",
"system/users/del/:ids": "del"
},
index: function(){
vs.user.list();
},
add: function(){
vs.user.add();
},
edit: function(id){
vs.user.edit(id);
},
del: function(ids){
vs.user.del(ids);
}
});
rs.Role = Backbone.Router.extend({
routes: {
"system/roles": "index",
"system/roles/add": "add",
"system/roles/edit/:id": "edit",
"system/roles/del/:ids": "del"
},
index: function(){
vs.role.list();
},
add: function(){
vs.role.add();
},
edit: function(id){
vs.role.edit(id);
},
del: function(ids){
vs.role.del(ids);
}
});
s.user = new s.User();
s.role = new s.Role();
return [rs, vs];
})(c.router.system || {}, c.view.system || {})
c.router.system = SystemRouterAndSystemView[0];
c.view.system = SystemRouterAndSystemView[1];
Backbone.history.start();
// route to first page
c.router.base.navigate('system', true);
return c;
})(company || {});
这样就完成的我们的项目的模块化改造,你已经看见在router中调用的是c.view.system.user.add()和c.view.system.role.add(),此function分别再两个js中,方法名都是add,这样我们的代码清爽多了,也不用在考虑命名冲突的问题了。
3. 谈一谈app.js的使用,我的app.js
var company = (function(c){
c.view.topMenu = new c.view.TopMenu().render();
c.view.secondMenu = new c.view.SecondMenu();
c.view.toolMenu = new c.view.ToolMenu();
c.view.mainTitleView = new c.view.MainTitle();
c.view.mainSearchView = new c.view.MainSearch();
c.view.mainOperationsView = new c.view.MainOperation();
c.view.mainContentView = new c.view.MainContent().render();
c.initMenusAndTools = function(currentTopMenu){
// overwrite view of secondMenu
c.view.secondMenusView.menus.reset();
_(currentTopMenu.children).each(function(menu){
c.view.secondMenusView.menus.add(new c.Menu(menu));
})
// overwrite view of toolMenu
c.view.toolMenu.collection.reset();
_(currentTopMenu.toolbar).each(function(menu){
c.view.toolMenu.collection.add(new c.model.Menu(menu));
})
}
return c;
})(company || {});
可以看得出来我对页面的基本框架的视图进行的默认的初始化,包括顶级菜单,二级菜单,工具栏,搜索栏,操作按钮集,重要内容显示区。这样只要修改相应的数据,对视图的部分进行修改就可以了。
initMenusAndTools是再模块切换(从system模块切换到chart模块)的时候初始化二级菜单和工具栏用的。
创建菜单的数据对象(JSON)。
// gloabal var for modularization
company = {}
company.model = {}
company.view = {}
company.coll = {}
company.router = {}
company.menus = [
{title: 'User', clazz: 'focus', action: '#user',
children: [
{title: '用户管理', clazz: 'user', action: '#system/users'},
{title: '角色管理', clazz: 'role', action: '#system/roles'}
],
toolbar: [
{title: '新建用户', clazz: 'newUser', action: 'javascript:void(0)'},
{title: '新建角色', clazz: 'newRole', action: 'javascript:void(0)'}
]
},
{title: 'Chart', clazz: '', action: '#chart'}
]
4. 再说一下项目中的公共组件。
// useage: new c.DisposableView({el: el, model: obj}).render('templateId');
c.DisposableView = Backbone.View.extend({
render: function(templateId, callback){
var template = _.template($('#' + templateId).html());
// The obj can be a native object or a instanceof Backbone.Model.
$(this.el).html(template({obj: _(this.model).nativeObj()}));
if(callback) callback();
return this;
}
})
这个一次性视图,根据指定的模版和对象来展现视图,为那些只适用一次的,仅仅用来展示的功能提供的。例如我们经常用的添加用户和添加角色等和业务相关的视图。
顺便说一下上面的nativeObj,这是我自定义的使用underscore的mixin整合的方法,目的就是将Backbone的model实例转换成js的本地对象,如果已经是本地对象则直接返回,代码如下:
_.mixin({nativeObj: nativeObj});
// if the object is Backbone.Model's instance and then change it to Native Object.
// if the object is Native and then return it.
function nativeObj(obj){
if(_(obj).isNull() || !_(obj).isObject()) return;
return (obj instanceof Backbone.Model) ? obj.toJSON() : obj;
}
5. 还有因为目前项目还没有使用requireJS,所有js的加载顺序要注意。
......
写了一大堆,更像是个人的总结,当然还没有结束,因为我也是刚开始用Backbone.js,以后还会进行更新。
分享到:
相关推荐
NULL 博文链接:https://elicer.iteye.com/blog/1935040
Node应用程序构建——使用MongoDB和Backbone
, 《backbone.js应用程序开发》详细介绍了如何使用backbone.js完成web应用开发。全书从了解mvc、spa和backbone.js的基本知识开始,然后着手构建3个示例应用程序;此外,backbone和grunt-bbb、jquery mobile等开发...
Node.js是一套用来编写高性能网络服务器的JavaScript工具包。...《Node应用程序构建——使用MongoDB和Backbone》可以作为学习和掌握Node.js、Backbone.js和MongoDB的实践教程,也适合对这几种技术感兴趣的读者阅读
Node.js是一套用来编写高性能网络服务器的JavaScript工具包。...《Node应用程序构建——使用MongoDB和Backbone》可以作为学习和掌握Node.js、Backbone.js和MongoDB的实践教程,也适合对这几种技术感兴趣的读者阅读
前端框架backbone使用教程.zip
, 《backbone.js应用程序开发》详细介绍了如何使用backbone.js完成web应用开发。全书从了解mvc、spa和backbone.js的基本知识开始,然后着手构建3个示例应用程序;此外,backbone和grunt-bbb、jquery mobile等开发...
《Node应用程序构建:使用MongoDB和Backbone》 源码,里面有git地址
Learn how Backbone.js brings MVC benefits to the client-side Write code that can be easily read, structured, and extended Work with the Backbone.Marionette and Thorax extension frameworks Solve ...
backbone 资料
backbone.d3, 使用 backbone.js 视图的可重用D3可视化 backbone.d3 backbone.d3 是一个 backbone.js 插件插件,它使用 D3.js 可视化库插件提供一组可重用图表。继续进行调优,了解更多信息 !版权和许可证版权所有 ...
《Backbone.js应用程序开发》详细介绍了如何使用Backbone.js完成Web应用开发。全书从了解MVC、SPA和Backbone.js的基本知识开始,然后着手构建3个示例应用程序。《Backbone.js应用程序开发》还介绍了Backbone和...
backbone-boilerplate, 一组用于构建 backbone.js 应用程序的最佳实践和实用工具 Backbone 模板这个样板是许多研究和挫折的产物。 现有的boilerplates修改 Backbone 核心,没有构建过程,或者者是非常规范的,这样的...
《backbone.js应用程序开发》先从了解mvc、spa和backbone的基本知识开始,然后着手构建示例应用程序——一个简单的todo列表应用程序、restful风格的图书应用程序、以及使用backbone和requirejs的模块化应用程序。...
backbone.js 1.1.2
Backbone.js API中文文档,供有需要的伙伴们使用。 Backbone.js API中文文档,供有需要的伙伴们使用。 Backbone.js API中文文档,供有需要的伙伴们使用。
Java 演示 backbone 基本用法 View Model Collection
Learn how Backbone.js brings MVC benefits to the client-side Write code that can be easily read, structured, and extended Work with the Backbone.Marionette and Thorax extension frameworks Solve ...
backbone官方Todo示例内含自己详细注释,建议运行之后打开浏览器调试同步学习。
react-backbone, Backbone 感知mixin用于响应和更多 反应中枢为 Backbone 提供对你的的响应,以响应你的组件,。将 backbone/backbone 。集合感知awareness你的反应组件mixin用于更新模型更改事件,请注意xhr活动和...