Backbone routing doesn't work when converted to TypeScript

时光怂恿深爱的人放手 提交于 2019-12-11 01:36:41

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!