我正在构建骨干中的应用程序,将https://github.com/addyosmani/backbone-aura/中的模块化和facade / mediator pub / sub模式组合在一起,以便在模块之间发送消息,以保持干净的代码库。
在光环的整个应用示例中为Router
加注,我发现只有自述文件描述了路由器作为模块本身一部分的理想用法:“在Backbone.js术语中,小部件由模型,视图组成,集合和路由器以及窗口小部件呈现所需的任何模板。“
所以我尝试了许多解决方案来实现可扩展的路由系统(可伸缩的意思模块可以指定自己的子路由),包括接受消息set-route
来设置路由的路由器模块,以及监听route
消息。我还为每个模块使用了一个子路由器。问题似乎是在初始页面加载时,由于消息传递的“异步”特性,路由及其回调可能不会在全局路由器解析URL时定义。你可以想象我可能需要在启动路由器模块之前排队所有消息。
我想实现干净的东西,这是有道理的。我还在考虑可能首先解析所有小部件的所有路由,然后实例化路由器,这使得路由器模块成为特殊情况,因此,不应该是模块的一部分。
路由器应该是一个使用消息的模块,还是应该是一个扩展,或者模块可以访问的全局架构的某些更高阶的部分?
我知道这是一个很复杂的问题,请提前感谢任何帮助!
答案 0 :(得分:1)
关于这个问题存在很多争论,我认为很多因为我认为对路由器的混淆正式称为控制器。当我去年年底开始使用Backbone时,已经进行了更改,但我相信很多人已经在路由器周围建立了应用程序作为控制器。我从不同意这一点。对我来说 - 在创建Backbone之前很久就依赖于构建类似于Backbone的专有MVC引擎的经验 - 路由器只是一个历史管理器组件。
为了解决您在决定如何最好地实施路由器方面的特定问题,请考虑以下几点:
下面是我在我的应用程序中使用的路由器模块的代码,该模块遵循介体,pub / sub模式:
/**
* The idea behind this component is simply to relegate Backbone.Router to
* doing what it does best: History Management. All it is responsible for
* is two things:
*
* 1. Update the URL if router.navigate is invoked
* 2. Trigger a routeChanged event if the URL was updated either by a bookmark or
* typed in by a user.
*/
define(function () {
return Backbone.Router.extend({
initialize : function (map) {
this._reversedMap = this.reverseModuleMap(map);
},
routes:{
'*actions':'notify'
},
notify:function (actions) {
var args = arguments;
this.trigger("routeChanged", {command:actions});
},
/**
* Override Backbone.Router.navigate. Default is to pass a router fragment, but for
* our uses, we'll translate the "route" into a module mapping so that the controller
* will know which module to display.
* @param param
* @param options
*/
navigate:function (param, options) {
//console.log('navigate', param);
if(!param.suppressNavigate && param.actionCommand) {
Backbone.Router.prototype.navigate.call(this, this._reversedMap[param.actionCommand]);
} else if(!param.actionCommand) {
Backbone.Router.prototype.navigate.call(this, param, options);
}
},
/**
* this function simply reverses the key and value of the "map"
* @param map
*/
reverseModuleMap:function (map) {
var newMap = {};
_.each(map, function (value, key) {
newMap[value] = key;
});
// reversed key and value
return newMap;
}
});
});
然后,当我实例化组件时,我将它传递给地图,以便我的控制器知道要导航到的模块:
this._router = new Router({
_default: 'moduleA',
sites : 'moduleA',
apps : 'moduleB'
});
this._router.on('routeChanged', this.handleRouteChange, this);
我发现最重要的是它使代码保持简洁,并使我能够专注于控制器中的业务逻辑。