Backbone.js路由而不更改url
我正在将基于Backbone.js和jQuery的单页Web应用程序迁移到Chrome扩展程序。 但是, pushState
和基于hashbang的路由器模式似乎都不适合扩展中的环境。 我得出的结论是,我最好只是直接渲染用户交互视图,完全绕过window.location
系统。 但是,我不太确定如何实现这一点,而无需在几十个文件中更改对Router.navigate
调用。
是否有可插拔/模块化的方式来保持Backbone路由系统但绕过对URL的任何更改?
我真的想坚持使用Router.navigate
从Backbone.js提供的路由系统中受益,而不必在Chrome扩展中使用时处理hashbang错误(例如包括斜线被覆盖的路由),你可以制作Router.navigate
直接加载url,跳过整个pushState体操。
这实际上很容易实现:
Router = Backbone.Router.extend({ navigate: function (url) { // Override pushstate and load url directly Backbone.history.loadUrl(url); }, // Put routes here routes: { } });
然后,您可以调用Router.navigate(url)
来加载新路由而不更改历史记录,甚至可以将操作绑定到包含data-backbone
属性的每个链接(例如Login
)这样的事件:
$(function(){ // Initialize router Router = new Router; Backbone.history.start(); // Bind a[data-backbone] to router $(document).on('click', 'a[data-backbone]', function(e){ e.preventDefault(); Router.navigate( $(this).attr('href') ); }); });
您可以重新定义Router.navigate
function,但最好不要完全使用Background.router。 我认为它可能会造成一些混乱,如果您当前正在从视图触发历史记录更改,那么如果没有它,您的代码将更加清晰。
Backbone.Marionette有一个控制器概念,它的工作方式很像没有URL映射的路由器(使用Marionette,其目的是保持路由定义最小化,并调用控制器来代替行为)。 您也不需要使用您不想要的任何Marionette组件。
如果你真的想坚持使用路由器,你可能只需重新定义Backbone.History.navigate
(注意,未经测试)
navigate: function(fragment, options) { if (!History.started) return false; if (!options || options === true) options = {trigger: options}; fragment = this.getFragment(fragment || ''); if (this.fragment === fragment) return; this.fragment = fragment; if (options.trigger) this.loadUrl(fragment); }