在Backbone中侦听路由事件不起作用 - 不调用附加功能

时间:2015-05-31 09:44:49

标签: javascript backbone.js

在Backbone JS项目中,我正在尝试侦听路由器发出的事件。来自docs

  

当访问者按下后退按钮或输入URL时,和   特定路线匹配,动作的名称将被触发   一个事件,以便其他对象可以收听路由器,并且可以   通知。

不幸的是,无论我使用on还是listenTo来监听路由器事件,我都无法解决此问题。

路由器看起来像这样:

var appRouter = Backbone.Router.extend({
  routes: {
    '' : 'index',
    'page(/:id)' : 'showPage'
  }
});

app.Router = new appRouter();
Backbone.history.start();

在视图的初始化函数中,我尝试监听这样的事件:

initialize: function () {
  this.listenTo(app.Router, 'route:showPage', this.myTestFn);
  app.Router.on('route:index', this.myTestFn);
},

对我而言,这看起来是正确的,但永远不会调用myTestFn

如何在Backbone JS中侦听路由事件?

1 个答案:

答案 0 :(得分:2)

这取决于您是否使用哈希或标准网址。

使用哈希网址

假设您使用的是哈希网址,那么您的设置是正确的。因此,如果你有类似下面的链接,你的代码将正常工作:

<a href="#">Index</a>
<a href="#page/1">First page</a>

我已经快速创建了一个包含您的代码和here

链接的jsfiddle

使用标准网址

如果您计划使用标准网址,则需要做更多工作。基本上你需要:

  1. 使用HTML5推送状态初始化Backbone history

    Backbone.history.start({pushState: true});
    
  2. 拦截链接上的点击事件,阻止浏览器向您的服务器发送完整的GET请求。您可以向视图添加事件或将全局事件处理程序用作in this nice article

  3. 手动告诉您的骨干路由器导航到截获的链接网址

    app.Router.navigate(href, {trigger: true});
    
  4. 例如,给出以下网址:

    <nav class="navLinks">
        <a href="/" class="standardUrlLink">Index</a>
        <a href="/page/1" class="standardUrlLink">First page</a>
    </nav>
    

    您可以拥有如下视图:

    var myView = Backbone.View.extend({
        el: ".navLinks",
        events: {
            "click .standardUrlLink": "standardUrlIntercepted"
        },
        initialize: function () {
          this.listenTo(app.Router, 'route:showPage', this.myTestFn);
          app.Router.on('route:index', this.myTestFn);
        },        
        standardUrlIntercepted: function(event) {
            //Get the link href and manually use backbone to navigate, triggering the route
            var href = $(event.currentTarget).attr("href");
            console.log("standard url intercepted, href=" + href);
            app.Router.navigate(href, {trigger: true});
            //Cancel default event behaviour (sending the GET request)
            return false;
        },
        myTestFn: function(){
            console.log("route called")
        }
    });
    

    我在this fiddle中使用此方法汇总了一个工作示例,因此您可以尝试一下。