Backbone.js路由而不更改url

时间:2013-06-27 04:18:28

标签: jquery backbone.js pushstate hashbang

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

是否有可插拔/模块化方式来保留Backbone路由系统但绕过对网址的任何更改?

2 个答案:

答案 0 :(得分:22)

我真的很想坚持使用Router.navigate从Backbone.js提供的路由系统中受益,而不必在Chrome扩展中使用时处理hashbang错误(例如包含斜线被覆盖的路由),你可以让Router.navigate直接加载网址,跳过整个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') );
  });

});

答案 1 :(得分:2)

您可以重新定义Router.navigate的功能,但最好不要完全使用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);
}