问题
I'm trying to convert a basic Backbone.js router declaration to TypeScript.
var AppRouter = Backbone.Router.extend({
routes: {
"*actions": "defaultRoute"
},
defaultRoute: function () {
document.write("Default Route Invoked");
}
});
var app_router = new AppRouter();
Backbone.history.start();
My converted code is the following which doesn't work:
class AppRouter extends Backbone.Router {
routes = {
"*actions": "defaultRoute"
}
defaultRoute() {
document.write("Default Route Invoked");
}
}
var app_router = new AppRouter();
Backbone.history.start();
I get no compile time or runtime errors but the code does not function. Why?
回答1:
I've had a look at Backbone.Router.extends
and it isn't a basic prototype extension - so you can't just switch from Backbone.Router.extends
to a TypeScript class extension.
I would change your TypeScript file to look more like your original JavaScript - you'll still get the benefit of intellisense and type checking - you just aren't using a class:
var AppRouter = Backbone.Router.extend({
routes: {
"*actions": "defaultRoute"
},
defaultRoute: function () {
document.write("Default Route Invoked");
}
});
var app_router = new AppRouter();
Backbone.history.start();
回答2:
As Steve Fenton mentioned it's because Typescripts extend does not work in the same way as underscore / backones extend method.
The main problem is that the router calls _bindRoutes() before your routes field has been set in the "sub class" in type scripts hierachy.
A call to Backbone.Router.apply(this, arguments) in the constructor of your ts class as described by orad, ensures that this call will be made after the routes field has been set.
A manual call to this function will do the trick as well.
and just a FYI: call delegateEvents(this.events) in the constructor of your view classes if you want the dom events from your element to get triggered
回答3:
Add all initialized fields in the constructor and make a call to super
at the end:
class AppRouter extends Backbone.Router {
routes: any;
constructor(options?: Backbone.RouterOptions) {
this.routes = {
"*actions": "defaultRoute"
}
super(options);
}
initialize() {
// can put more init code here to run after constructor
}
defaultRoute() {
document.write("Default Route Invoked");
}
}
var app_router = new AppRouter();
Backbone.history.start();
回答4:
The accepted answer doesn't seem to work with typescript 3.x . The super()
method should be called before using this
. Reordering code won't work because backbone is initializing routes within the super()
method. Here is a version where the route configuration is directly passed to super()
.
class AppRouter extends Backbone.Router {
constructor() {
super({
routes: {
"*actions": "defaultRoute"
}
});
}
}
来源:https://stackoverflow.com/questions/14594996/backbone-routing-doesnt-work-when-converted-to-typescript