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

时间:2012-03-02 00:21:53

标签: javascript backbone.js url-routing

目前正在构建一款在手机上运行的应用 与手头的问题无关,而是通过某一事件 该应用程序登陆状态,无论是在线还是离线(可通过电话上网等)

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

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

就像你可以在集合上定义动态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();抛出错误时,无法调用函数从undefined启动。 让我相信我的路线对象在初始化时以某种方式使用,无法动态更改。

我可能想到远吗? 我应该以其他方式实现这一目标吗?

我的其他想法是:

  • 路由与url完全一样,其中routes参数是一个返回哈希的函数,不起作用
  • 现在我的想法完全不同了,如果应用程序在每个路径的动作中处于在线或离线状态,那么就会有一些测试。虽然这似乎太多了,但我可能不得不通过一个Action来传递它们,如果在离线模式下可以访问路由,它只传递给实际的动作?但是如果没有编写过多的样板代码,我真的不清楚如何开始这样的继电器动作......

2 个答案:

答案 0 :(得分:1)

为了动态更新路线,您需要在更新路线后调用_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时,它会在调用this.route时自动实例化一个新的Backbone.history。

答案 1 :(得分:0)

我必须做一些非常相似的事情。我没有在我面前的代码,但这应该是我的所作所为:(编辑:充实它,所以你现在可以实际运行它)

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()。