Backbone.js如何根据特定的应用程序状态定义一组自定义路由

Backbone.js how do i define a custom set of routes depending on a certain application state

本文关键字:定义 路由 自定义 一组 程序状态 应用 何根 js Backbone      更新时间:2023-09-26

当前正在构建一个在手机上运行的应用程序与手头的问题无关,而是通过某个事件该应用程序处于在线或离线状态(无论手机上是否有互联网)

离线应用程序非常有限,只有几个屏幕可用)

现在,如果你发现我在做一些愚蠢的事情,或者我可以做得更好的事情,请阻止我,但我的第一个想法是让路由器有一组动态的路由,

就像可以在集合上定义动态url属性一样。

因此:

var router = Backbone.Router.extend({
    routes: {
        '' : 'homeAction',
        'categories' : 'categoriesAction',
        ...
    },
    homeAction: function(){ },
    categoriesAction: function(){ }
});

我在想:

var router = Backbone.Router.extend({
    initialize: function(){
        this.on('app:togglestate', this.toggleRoutes, this);
    },
    toggleRoutes: function () {
        var router = this;
        if(App.onlineModus)
            router.routes = { /* hash with online routes here */ };
        else
            router.routes = { /* hash with offline routes here */ };
    },
    routes: {
        '' : 'homeAction',
        'categories' : 'categoriesAction',
        ...
    },
    homeAction: function(){ },
    categoriesAction: function(){ }
});

尽管这显然破坏了整个应用程序,由于Backbone.history.start();抛出错误,因此无法调用从未定义开始的函数。这让我相信routes对象是在初始化时以某种方式使用的,不能在运行中更改。

我可能想得太远了吗?我应该以其他方式实现这一点吗?

我的另一个想法是:

  • 路由与url完全相同,routes参数是一个返回哈希的函数,但这也不起作用
  • 现在我的想法完全不同了,在测试应用程序在每条路线的Action中是在线还是离线模式的过程中。虽然这看起来太模糊了,但我可能不得不通过一个动作来传递它们,只有在离线模式下可以访问路由的情况下,这个动作才会传递到实际动作?但如果不写太多的样板代码,我真的不知道如何开始这样的中继动作

为了动态更新路由,您需要在更新路由后调用_bindRoutes()。

例如:

toggleRoutes: function () {
    var router = this;
    if(App.onlineModus)
        router.routes = { /* hash with online routes here */ };
    else
        router.routes = { /* hash with offline routes here */ };
    // Get rid of previous navigation history
    if(Backbone.history){
        Backbone.history == null;
    }
    // Bind the new routes
    router._bindRoutes();
}

请注意,当您动态更改路线时,历史记录将不再有效,因此您需要删除以前的历史记录。当调用_bindRoutes时,它会自动实例化一个新的Backbone.history当调用this.route.时

我不得不做一些非常类似的事情。我面前没有代码,但这应该是我所做的:(编辑:将其充实一点,这样你现在就可以真正运行它了)

ApplicationRouter = Backbone.Router.extend({
    //some stuff
    constructor: function (routes) {
        this.routes = routes;
        Backbone.Router.prototype.constructor.call(this);
    }
});
routeObject = {
    "help": "help"
}
ApplicationRouter.instance = function(routes) {
    if (!this._instance) {
        this._instance = new ApplicationRouter(routes);
    }
    return this._instance;
}
ApplicationRouter.instance(routeObject);
ApplicationRouter.instance().on('route:help', function() {
    console.log('helped');
});
Backbone.history.start();
//now go to page#help - the console will say "helped"

从那时起,当我需要访问应用程序路由器时,我只引用ApplicationRouter.instance()。