13

我正在将基于 Backbone.js 和 jQuery 的单页 Web 应用程序迁移到 Chrome 扩展程序。但是,无论是基于 hashbang 的路由器模式,pushState还是基于 hashbang 的路由器模式,似乎都不能很好地适应扩展中的环境。我得出的结论是,我最好直接渲染用户交互的视图,window.location 完全绕过系统。但是,我不太确定如何在不更改对Router.navigate数十个文件的调用的情况下实现这一点。

是否有一种可插入/模块化的方式来保留主干路由系统但绕过对 url 的任何更改?

4

2 回答 2

22

我真的想坚持使用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属性(例如<a href="login" data-backbone>Login</a>)的每个链接,并带有如下事件:

$(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') );
  });

});
于 2013-06-27T23:47:07.363 回答
2

你可以重新定义做什么Router.navigate,但你最好不要完全使用 Background.router。我认为这可能会造成一些混乱,如果您当前正在从视图中触发历史更改,那么如果没有它,您的代码会更干净。

Backbone.Marionette有一个控制器的概念,它的工作原理很像没有 URL-map 的路由器(使用 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);
}
于 2013-06-27T06:01:51.663 回答