【问题标题】:navigate route with querystring使用查询字符串导航路线
【发布时间】:2012-07-25 03:55:48
【问题描述】:

Backbone.Router.navigate 设置为testtrue

var test = false;

var Router = Backbone.Router.extend({
  routes: {
    'posts': 'showPosts'
  },
  showPosts: function () {
    test = true;
  }
});

router = new Router();
Backbone.history.start();

router.navigate('posts?foo=3', {trigger: true});

assert.ok(test);

例如,posts?foo=3 片段是否会默认匹配 posts 路由,还是我必须为此设置另一个路由,例如:posts?*querystring

谢谢

PS:我知道存在backbone-query-parameters,但我只想知道主干。

【问题讨论】:

标签: backbone.js backbone-routing


【解决方案1】:

您需要使用该预期参数添加另一条路线:

routes: {
    'posts?foo=:foo' : 'showPosts',
    'posts': 'showPosts'
},
showPosts: function (foo) {
    if(typeof foo != 'undefined'){
       // foo parameters was passed
    }
    test = true;
}

更新
您可以定义返回所有查询字符串的通用路由,然后在处理程序中对其进行解析:

routes: {
   'posts': 'showPosts',
   'posts?*queryString' : 'showPosts'
},
showPosts: function (queryString) {
    var params = parseQueryString(queryString);
    if(params.foo){
        // foo parameters was passed
    }
}  
...
// and the function that parses the query string can be something like : 
function parseQueryString(queryString){
    var params = {};
    if(queryString){
        _.each(
            _.map(decodeURI(queryString).split(/&/g),function(el,i){
                var aux = el.split('='), o = {};
                if(aux.length >= 1){
                    var val = undefined;
                    if(aux.length == 2)
                        val = aux[1];
                    o[aux[0]] = val;
                }
                return o;
            }),
            function(o){
                _.extend(params,o);
            }
        );
    }
    return params;
}

更新 2

这里是a live demo 以查看正在运行的代码。

【讨论】:

  • 在一种情况下,您首先定义最具体的路线 (posts?foo=:foo),而在另一种情况下,在第二个位置:顺序不重要吗?
  • 不,它不会影响路由的应用方式。这只是一个偏好问题。顺便说一句,我已经测试并更新了该功能,现在效果很好。
  • 我看到这个演示工作,但由于我仍然无法理解的原因,这对我不起作用。使用这些路由构造,queryString 总是未定义的。
  • 我知道问题出在哪里 - 虽然您可以通过传递 true 来导航来执行路线,但这仍然无法正确处理历史记录。此外,必须通过 true 进行导航并不理想,因为它需要我的路由器执行导航,而不是简单地执行解释路由。
  • 这个答案与最初的问题相去甚远...您的答案现在更像是如何解析查询字符串...
【解决方案2】:

只是为了补充前面的答案,而不是定义两个具有相同回调的路由,例如:

routes: {
    'posts': 'showPosts',
    'posts?*querystring': 'showPosts'
}

你可以只有一种方法来保持代码更清晰:

routes: {
    'posts(?*querystring)': 'showPosts'
}

【讨论】:

  • 在使用 URI 编码的查询参数(例如“foo=Max%20%26%20Moritz”)时无法匹配整个查询字符串,因为backbone.js只需要完整的路径片段,并且已经在每个路由参数上调用了 decodeURIComponent。因此稍后解析查询字符串将无法正常工作。
【解决方案3】:

主干文档:

路由可以包含参数部分,:param,它匹配斜线之间的单个 URL 组件;和 splat 部分 *splat,可以匹配任意数量的 URL 组件。

如果你仍然想保留功能而不匹配,你可以定义两个路由

routes: {
  'posts': 'showPosts',
  'posts?*querystring': 'showPosts'
}

showPosts: function(querystring) {
  if (querystring) {
    // here you can parse your querystring, for your case the querystring variable is 
    // 'foo=3'
  }
  //here you'll show posts according to the querystring (or lack thereof)      
}

【讨论】:

  • ?* 是否没有 splat 的名称 ?*querystring 好吗?
  • 这应该在 Backbone 1 中工作吗? Cz 在我添加“?*查询”后它没有触发任何路由操作
  • 答案是大约一年前提出的。但是文档或变更日志并没有暗示任何原因导致这不起作用
  • 我遇到了同样的问题。有一个带有 ?*queryString 的路由不仅不会捕获 queryString 变量,而且如果我有这个而不是没有查询字符串的路由,那么路由根本不会被解释。
【解决方案4】:

这是另一个例子,仍然使用 lodash(下划线)。删除了 _.map,为变量添加了一些详细信息,并去掉了开头的“?”如果存在:

function parseQueryString(queryString)
{
    if (!_.isString(queryString))
        return
    queryString = queryString.substring( queryString.indexOf('?') + 1 )
    var params = {}
    var queryParts = decodeURI(queryString).split(/&/g)
    _.each(queryParts, function(val)
        {
            var parts = val.split('=')
            if (parts.length >= 1)
            {
                var val = undefined
                if (parts.length == 2)
                    val = parts[1]
                params[parts[0]] = val
            }
        })
    return params
}

【讨论】:

  • 谢谢你,我应该得到更多的关注
【解决方案5】:

RFC 3986“URI 语法”规定查询参数应位于哈希片段之前。

在 URI 中,井号 # 在 URL 末尾附近引入可选片段。 URI 的通用 RFC 3986 语法还允许由问号 ? 引入可选的查询部分。在带有查询和片段的 URI 中,片段跟随查询。

我在处理从服务器获取的重定向时遇到了这个问题,即“http://foo.com/main.html?error=errormessage#site”。我想对查询进行路由,但看不到编写主干路由表达式来处理此 url 的方法。现在我只是在哈希上路由并通过解析 location.search 来检查查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    • 1970-01-01
    • 2015-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多