【问题标题】:Handling view options via Backbone routes通过主干路由处理视图选项
【发布时间】:2013-04-03 18:25:48
【问题描述】:

我已经开发大型 Backbone Marionette 应用程序大约一年了。一直具有挑战性的一件事是传递路线中视图状态的选项。视图状态选项的示例是活动选项卡、临时选择的项目或页面上需要可链接的排序选项。

在更新到 Backbone 0.9.9+ 之前,我发现处理这些情况的最佳方法是将查询参数添加到路由的末尾。我的路由器看起来像这样:

"/questions/:id/"         : "showQuestions"
"/questions/:id/?*params" : "showQuestionsWithFilters"

匹配如下:

"/questions/1/?search=help&sort=name"

我发现这样做的真正优势是路由器将根据 url 参数的存在匹配不同的路由。清除所有url参数,然后触发导航,实际上会导致路由改变。

Backbone 0.9.2 之后路由器不再识别 url 参数。在上面的示例中,无论是否存在 url 参数,都会触发“showQuestions”方法。在这个 GH 问题 (https://github.com/documentcloud/backbone/issues/891) 中的普遍共识和 Backbone 贡献者的意见似乎是 url 参数根本不应该在客户端使用,而是所有需要传递给视图的信息应该是存储在主 url 路径 (https://github.com/documentcloud/backbone/issues/2440) 中。

使用这种方法的路由器可能看起来像:

"/questions/:id/(search/:term)(sort/:type/)"

这种方法的问题是每个可选参数都需要显式添加到路由器,并且所有参数都必须相应地排序,否则它们将不匹配。因为在路由和它的选项之间没有轮廓线,并且顺序是由路由器决定的,所以动态添加或编辑选项似乎是不必要的困难。

在这一点上,我在保持我当前的 url 结构和试图找出一种使它工作的方法或迁移到后一种方法之间陷入困境。在我朝任何一个方向走得太远之前,我想知道是否对类似用例的最佳实践还有其他意见。 你会推荐什么?

【问题讨论】:

    标签: backbone.js marionette


    【解决方案1】:

    还有一条路线称为 splat。来自http://backbonejs.org/#Router

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

    在我的应用中,我使用了一个必需的参数,然后是任意数量的可选“过滤器”:

    var BrowseRouter = Marionette.AppRouter.extend({
      appRoutes: {
        'browse/:page(/*filters)': 'browse'
      }
    });
    

    然后,我的 URL 被格式化为一系列由斜杠分隔的键/值对:#/browse/3/type:image/sort:date/count:24

    在我的控制器中,我向函数传递了两个参数:pagefilterspage 是一个简单的值(“3”)。 filters 是可选的,是一个较长的字符串,包含页面值之后的所有内容(“type:image/sort:date/count:2”)。

    我有一个“explode”下划线 mixin 来获取该字符串并将其转换为一个对象。

    _.mixin({
      /*
       * Take a formatted string (from the URL) and convert it into an object of
       * key/val pairs. If the val looks like an array, make it so.
       * _.explode("count:105/sort:date/type:image,video")
       * => { count: 105, sort: date, type: ['image','video']}
       */
      explode: function(str) {
        var result = {};
        if(!str){
            return result;
        }
        _.each(str.split('/'), function(element, index, list){
          if(element){
            var param = element.split(':');
            var key = param[0];
            var val = param[1];
            if (val.indexOf(",") !== -1) {
              val = val.split(',');
            }
            result[key] = val;
          }
        });
        return result;
      }
    });
    

    【讨论】:

    • 这是一种非常有趣的处理方式。我肯定会考虑实施类似的东西。感谢您的回复!
    • 另一种可能性是使用骨干查询参数插件 [github.com/jhudson8/backbone-query-parameters]。它扩展了路由器以允许自动解码为对象的 ?params。我最初使用它,但它与 pushState 不兼容,所以我不得不换档并想出别的东西。
    猜你喜欢
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2016-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多