Backbone.js:获取当前路由

1hdlvixo  于 2022-11-10  发布在  其他
关注(0)|答案(7)|浏览(186)

我知道如何绑定到路线更改事件,但我希望能够在其他时间,在更改之间确定当前路线。

9jyewag0

9jyewag01#

如果在应用程序中示例化了路由器,则以下行将返回当前片段:

Backbone.history.getFragment();

在Backbone.js文档中:
“[...]历史作为一个全局路由器(每帧)来处理hashchange事件或pushState,匹配适当的路由,并触发回调。你不应该自己创建其中的一个-你应该使用对Backbone的引用。如果你使用路由器,历史将自动为你创建。[...]”
如果需要绑定到该片段的函数的名称,可以在Router的作用域中创建类似如下的内容:

alert( this.routes[Backbone.history.getFragment()] );

或者从路由器外部执行以下操作:

alert( myRouter.routes[Backbone.history.getFragment()] );
lf3rwulv

lf3rwulv2#

Robert's answer很有意思,但遗憾的是,只有当哈希值与路由中定义的完全一致时,它才能工作。(这两者都是这种路由的两个最明显的用例)。换句话说,它只会在哈希值恰好为"user(/:uid)"时找到合适的回调名称(这种可能性很小)。
因为我需要这个功能,我用current函数扩展了Backbone.Router,这个函数重用了History和Router对象使用的一些代码,以将当前片段与定义的Routes匹配,从而触发适当的回调。如果设置为任意值,将返回为路由定义的相应函数名,否则将返回来自Backbone.History.fragment的当前哈希片段。
您可以将代码添加到现有的Extend中,在Extend中初始化和设置 Backbone 路由器。

var Router = new Backbone.Router.extend({

    // Pretty basic stuff
    routes : {
        "home" : "home",
        "user(:/uid)" : "user",
        "test" : "completelyDifferent"
    },

    home : function() {
        // Home route
    },

    user : function(uid) {
        // User route
    },

    // Gets the current route callback function name
    // or current hash fragment
    current : function(route){
        if(route && Backbone.History.started) {
            var Router = this,
                // Get current fragment from Backbone.History
                fragment = Backbone.history.fragment,
                // Get current object of routes and convert to array-pairs
                routes = _.pairs(Router.routes);

            // Loop through array pairs and return
            // array on first truthful match.
            var matched = _.find(routes, function(handler) {
                var route = handler[0];

                // Convert the route to RegExp using the 
                // Backbone Router's internal convert
                // function (if it already isn't a RegExp)
                route = _.isRegExp(route) ? route :  Router._routeToRegExp(route);

                // Test the regexp against the current fragment
                return route.test(fragment);
            });

            // Returns callback name or false if 
            // no matches are found
            return matched ? matched[1] : false;
        } else {
            // Just return current hash fragment in History
            return Backbone.history.fragment
        }
    }
});

// Example uses:
// Location: /home
// console.log(Router.current()) // Outputs 'home'
// Location: /user/1
// console.log(Router.current(true)) // Outputs 'user'
// Location: /user/2
// console.log(Router.current()) // Outputs 'user/2'
// Location: /test
// console.log(Router.current(true)) // Outputs 'completelyDifferent'

我确信还可以做一些改进,但这是一个很好的入门方法。而且,创建这个功能很容易,而不需要扩展Route-object。我这样做是因为这是我设置的最方便的方法。

我还没有完全测试过,所以如果有任何问题,请告诉我

更新日期:2013年4月25日

我对函数做了一些修改,所以我返回一个带有fragment、params和route的对象,而不是返回hash或route回调名称,这样您就可以访问当前route中的所有数据,就像您从route-event中访问数据一样。
您可以看到以下更改:

current : function() {
    var Router = this,
        fragment = Backbone.history.fragment,
        routes = _.pairs(Router.routes),
        route = null, params = null, matched;

    matched = _.find(routes, function(handler) {
        route = _.isRegExp(handler[0]) ? handler[0] : Router._routeToRegExp(handler[0]);
        return route.test(fragment);
    });

    if(matched) {
        // NEW: Extracts the params using the internal
        // function _extractParameters 
        params = Router._extractParameters(route, fragment);
        route = matched[1];
    }

    return {
        route : route,
        fragment : fragment,
        params : params
    };
}

请参阅前面的代码以获取更多注解和解释,它们看起来基本相同。

xwbd5t1u

xwbd5t1u3#

要从被调用的路由处理程序获取调用路由(或url),可以通过选中

Backbone.history.location.href  ... the full url
Backbone.history.location.search  ... query string starting from ?

我来这里是为了寻找这个答案,所以我想我应该留下我找到的东西。

rwqw0loc

rwqw0loc4#

如果您使用路由器的根设置,您还可以包括它以获得“真实的的”片段。

(Backbone.history.options.root || "") + "/" + Backbone.history.fragment
au9on6nz

au9on6nz5#

下面是Simon's answer的一个 tad 更详细(或者,根据您的喜好,更易读)的版本:

current: function () {
  var fragment = Backbone.history.fragment,
      routes = _.pairs(this.routes),
      route,
      name,
      found;

  found = _.find(routes, function (namedRoute) {
    route = namedRoute[0];
    name = namedRoute[1];

    if (!_.isRegExp(route)) {
      route = this._routeToRegExp(route);
    }

    return route.test(fragment);
  }, this);

  if (found) {
    return {
      name: name,
      params: this._extractParameters(route, fragment),
      fragment: fragment
    };
  }
}
r8xiu3jd

r8xiu3jd6#

如果您查看Router的源代码,您会发现当路由器触发事件表示发生了更改时,它会以“route:name”的形式传递名称。
http://documentcloud.github.com/backbone/docs/backbone.html#section-84
您可以始终在路由器上挂接“route”事件并存储它以获取当前路由。

rsaldnfx

rsaldnfx7#

router = new Backbone.Router.extend({
  routes: { "stuff/:id" : "stuff" },
  stuff: function(id) {}
});

router.on('route', function(route) {
  this.current = route;
});

现在,如果您导航到/stuff/1,router.current将是“stuff”

相关问题