Backbone.js 路由而不更改 url

Posted

技术标签:

【中文标题】Backbone.js 路由而不更改 url【英文标题】:Backbone.js routing without changing url 【发布时间】:2013-06-24 10:36:19 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

我你真的想坚持使用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') );
  );

);

【讨论】:

【参考方案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);

【讨论】:

AppRouter 应该被用来代替路由器。现在不推荐使用 Marionette Controller 类 - 任何对象都可以用作 AppRouter 使用的控制器。

以上是关于Backbone.js 路由而不更改 url的主要内容,如果未能解决你的问题,请参考以下文章

Backbone.js:未达到路由器回调

Backbone.js - 导航时出现 404 jQuery 错误

Backbone.js URL 路由

使用 Jasmine 监视 Backbone.js 路由调用

Backbone.js 控制器中的默认路由?

Backbone.js 路由器初始化不会立即运行