我认为在数据驱动的编程范式中,路由器和视图应该相互隔离,它们只能通过模型更改来相互通信,它们都订阅了模型更改。
但是,在线的各种教程都以不同的方式执行此操作。我已经看到在路由器的初始化方法中实例化视图的代码,从而为路由器提供了访问视图的方法。我还看到了将路由器传递给视图的代码,以便视图可以监听路由器路由事件的变化。
我不相信这两种方法都是正确的,因为它打破了关注点的分离。由于我是 Backbone 的新手,有经验丰富且知识渊博的人可以确认吗?
我认为在数据驱动的编程范式中,路由器和视图应该相互隔离,它们只能通过模型更改来相互通信,它们都订阅了模型更改。
但是,在线的各种教程都以不同的方式执行此操作。我已经看到在路由器的初始化方法中实例化视图的代码,从而为路由器提供了访问视图的方法。我还看到了将路由器传递给视图的代码,以便视图可以监听路由器路由事件的变化。
我不相信这两种方法都是正确的,因为它打破了关注点的分离。由于我是 Backbone 的新手,有经验丰富且知识渊博的人可以确认吗?
我没有看到使用路由器实例化视图有任何问题,实际上是我使用的工作方式。路由器检测到一个新的 URL 并分离任何未使用的视图并实例化请求的视图。
将 Router 引用传递给 View 可能会更丑陋,更不用说为了保持引用在 View 和 SubView 之间传播而付出了太多努力。
但另一方面,视图必须能够向路由器发送信号以更改导航,因此我也采用简单的方法,使路由器对我的应用程序中的所有元素全局可见,我可以App.router.navigate()
从任何视图调用而无需请记住明确传递引用。这个决定可以辩护,因为在任何 Backbone 应用程序中只允许一个路由器实例。
在一些项目中,我使用了一个全局事件调度器,它将路由事件传递给视图。
window.Dispatcher = _.extend({}, Backbone.Events);
在路由器中,您可以绑定到'all'
捕获事件的route:*
事件:
initialize: function() {
this.bind('all', this.onRoute);
},
onRoute: function(route) {
Dispatcher.trigger(route);
}
在您的视图中,您可以绑定到 Dispatcher 事件并对路由更改做出反应:
initialize: function() {
Dispatcher.on('route:index', this.onIndex, this)
}
这类似于在路由更改时更改模型,但我觉得这更易于管理,并且不需要将路由器传递给视图。不确定这是否是正确的方法,但是 Backbone 再次使您能够以多种不同的方式做事。