侦听 Backbone 中的路由事件不起作用 – 未调用附加函数
Listening for route events in Backbone not working – attached function is not called
在一个 Backbone JS 项目中,我试图监听路由器发出的事件。来自 docs:
When the visitor presses the back button, or enters a URL, and a
particular route is matched, the name of the action will be fired as
an event, so that other objects can listen to the router, and be
notified.
不幸的是,无论我使用 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 中监听路由事件?
这取决于您使用的是散列还是标准 urls。
使用散列urls
假设您使用的是散列 urls,则您的设置是正确的。所以如果你有像下面这样的 links,你的代码将工作正常:
<a href="#">Index</a>
<a href="#page/1">First page</a>
我已经用你的代码和那些 links here
快速创建了一个 jsfiddle
使用标准 urls
如果您打算使用标准 urls,则需要做更多的工作。基本上你需要:
使用HTML5推送状态初始化Backbone history
Backbone.history.start({pushState: true});
拦截您 link 上的点击事件,防止浏览器向您的服务器发送完整的 GET 请求。您可以将事件添加到您的视图或使用全局事件处理程序作为 in this nice article.
手动告诉你的backbone路由器导航到拦截的linkurl
app.Router.navigate(href, {trigger: true});
例如给出以下 urls:
<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 中整理了一个使用这种方法的工作示例,您可以尝试一下。
在一个 Backbone JS 项目中,我试图监听路由器发出的事件。来自 docs:
When the visitor presses the back button, or enters a URL, and a particular route is matched, the name of the action will be fired as an event, so that other objects can listen to the router, and be notified.
不幸的是,无论我使用 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 中监听路由事件?
这取决于您使用的是散列还是标准 urls。
使用散列urls
假设您使用的是散列 urls,则您的设置是正确的。所以如果你有像下面这样的 links,你的代码将工作正常:
<a href="#">Index</a>
<a href="#page/1">First page</a>
我已经用你的代码和那些 links here
快速创建了一个 jsfiddle使用标准 urls
如果您打算使用标准 urls,则需要做更多的工作。基本上你需要:
使用HTML5推送状态初始化Backbone history
Backbone.history.start({pushState: true});
拦截您 link 上的点击事件,防止浏览器向您的服务器发送完整的 GET 请求。您可以将事件添加到您的视图或使用全局事件处理程序作为 in this nice article.
手动告诉你的backbone路由器导航到拦截的linkurl
app.Router.navigate(href, {trigger: true});
例如给出以下 urls:
<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 中整理了一个使用这种方法的工作示例,您可以尝试一下。