对主干集合进行排序

2024-03-30

所需的功能

我正在使用 Backbone.Collection 来查看可排序列表中的数据。我已经得到了单击某些 dom 元素会在我的 Collection 上设置属性的部分,以确定我想要排序的字段以及应该进行哪个方向的排序。 然后应该在集合上触发排序,之后视图将更新。

最终我希望能够对数字字段和字符串进行排序。某些字符串应按字母顺序排序,其他字符串应按自定义预定义顺序排序。

我目前的做法

我发现以下关于反向排序字符串的帖子:使用backbone.js 对字符串进行逆序排序 https://stackoverflow.com/questions/5636812/sorting-strings-in-reverse-order-with-backbone-js

我尝试将其与比较器函数和以下自定义属性结合起来:

  1. “状态”字段中可能值的自定义排序顺序
  2. 应该使用哪个字段进行排序
  3. 向哪个方向排序

到目前为止我得到的 Collection 和 Model 类:

收藏品

var ApplicationCollection = Backbone.Collection.extend({
  model: ApplicationModel,
  url: 'rest/applications',

  // sorting
  statusOrder: ['new', 'to_pay', 'payed', 'ready'],
  sortField: 'submission_timestamp',
  sortOrder: 'asc',
  sortBy: function() {
    console.log('ApplicationCollection.sortBy', this, arguments);
    console.log('this.comparator', this.comparator);
    var models = _.sortBy(this.models, this.comparator);
    if (this.sortOrder != 'asc') {
      models.reverse();
    }
    return models;
  },
  comparator: function(application) {
    console.log('ApplicationCollection.comparator', this, arguments);
    switch(this.sortField) {
      case 'status':
        return _.indexOf(this.statusOrder, application.get(this.sortField));
        break;
      case 'submission_timestamp':
      default:
        return application.get(this.sortField)
        break;
    }
  }
});

该模型

var ApplicationModel = Backbone.Model.extend({
  defaults: {
    'drupal_id': 0,
    'language': '',
    'last_name': '',
    'first_name': '',
    'address': '',
    'zip_code': '',
    'city': '',
    'country': '',
    'telephone': '',
    'cell_phone': '',
    'email': '',
    'date_of_birth': '',
    'email': '',
    'date_of_birth': '',
    'pilot_training_institute': '',
    'date_of_exam': '',
    'flight_hours_total': '',
    'date_of_last_flight': '',
    'date_of_mcc_certificate': '',
    'date_of_ir_renewel': '',
    'package': '',
    'submission_timestamp': '',
    'status': 'new'
  },
  urlRoot: 'rest/applications'
});

当前(不需要的)结果

我有一个存储在“pendingApplications”中的集合实例,如下所示:

var pendingApplications = new ApplicationCollection();
pendingApplications.fetch();

这将从服务器加载应用程序,并且一切都按计划进行。我可以渲染一个包含应用程序列表的视图,所有属性都在模型上,等等。

为了对集合进行排序,我执行以下操作:

pendingApplications.sortOrder = 'asc';
pendingApplications.sortField = 'current_timestamp'; // format: YYYY-mm-dd HH:mm:ss
pendingApplications.sort();

这会触发集合上的排序功能。控制台告诉我“ApplicationCollection.sortBy”方法在“pendingApplications”实例的范围内执行,这是预期的。

但是,“ApplicationCollection.comparator”方法在全局范围内执行,我不确定为什么。此外,比较器方法的参数都不包含“pendingApplications”实例。

我希望我的比较器方法在“pendingApplications”实例的范围内执行,或者至少我希望能够以某种方式访问​​“pendingApplications”实例上的属性。

范围问题?错误的做法?欢迎任何建议...

有谁知道我该如何解决这个问题?或者我是否以错误的方式处理这个问题,是否有另一种解决方案可以在 Backbone.Collection 上任意定义自定义排序?

解决方案

我最终实现了排序功能作为 Backbone.Collection 的装饰器。 这样做的原因是因为我还有一个用于过滤集合中的项目的装饰器。 通过使用排序装饰器,我可以将排序应用于过滤后的项目子集,这可能会更快。

/**
 * returns a new Backbone.Collection which represents a sorted version of the
 * data contained within the original Backbone.Collection.
 *
 * @param {Backbone.Collection} original
 */
SortedCollection: function(original, criteria) {
  var sorted = new original.constructor(),

  // sensible defaults
  defaultSortCriteria = {
    custom: {},
    field: 'id',
    direction: 'asc'
  };

  // configuration
  sorted.sortCriteria = _.extend(defaultSortCriteria, criteria);

  // do the stuff
  sorted.comparator = function(a, b) {
    // @formatter:off
    var criteria = this.sortCriteria,
        custom, 
        field = criteria.field,
        direction = criteria.direction,
        valA,
        valB;
        // @formatter:on

    // custom sort
    if (_.has(criteria.custom, field)) {
      custom = criteria.custom[field];

      // custom param is a comparator itself.
      if (_.isFunction(custom)) {
        return custom(a, b);
      }
      // custom param is an example of a sorted array.
      else if (_.isArray(custom)) {
        valA = _.indexOf(custom, a.get(field));
        valB = _.indexOf(custom, b.get(field));
      }
      else {
        throw new Error('Invalid custom sorting criterium.');
      }
    }
    // nothing custom here, use the field value directly.
    else {
      valA = a.get(field);
      valB = b.get(field);
    }

    // compare that shizzle!
    if (valA > valB) {
      return (direction == 'desc') ? -1 : 1;
    }
    if (valA < valB) {
      return (direction == 'desc') ? 1 : -1;
    }
    else {
      if (a.get('id') > b.get('id')) {
        return (direction == 'desc') ? -1 : 1;
      }
      else if (a.get('id') < b.get('id')) {
        return (direction == 'desc') ? 1 : -1;
      }
      else {
        return 0;
      }
    }
  };

  // update collection if original changes
  original.on("add", function(model) {
    sorted.add(model);
  });
  original.on("reset", function() {
    sorted.reset(original.models);
  });
  original.on("remove", function(model) {
    sorted.remove(model);
  });

  return sorted;
}

装饰器的用法:

original = new ApplicationsCollection();
sortable = SortedCollection(original);
sortable.sortCriteria = { 
  sortField: 'submission_timestamp',
  sortDirection: 'desc'
}
sortable.sort();

上面的代码片段执行以下操作:

  • 实例化一个新的ApplicationsCollection;
  • 实例化一个可排序集合,该集合扩展了原始集合并侦听原始集合上的相关事件。
  • 告诉可排序集合按“submission_timestamp”属性按降序排序。
  • 对可排序集合进行排序。

当新模型添加到原始集合或从原始集合中删除时,或者重置原始集合时,新的可排序集合也会自动保持排序。


The comparator()默认情况下,函数在集合范围内调用,至少在最新版本的 Backbone 中是这样。

我怀疑你可能已经通过定义sortBy()功能。该函数已由 Backbone 定义,并由 Backbone 内部使用sort()在某些情况下起作用。尝试删除该功能并查看它是否按预期工作。

看来您只是在使用sortBy()颠倒排序的顺序。这可以在comparator()函数的方法是在适当的时候将返回值乘以 -1。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对主干集合进行排序 的相关文章

  • javascript 中对象的“异步”循环

    通常 我们可以对数组和对象进行循环来迭代属性 值 但循环是阻塞的 但是 超时可用于模拟异步循环 我设法为数组做到了这一点 http jsfiddle net LHhy2 do stuff function asyncLoop i do st
  • pubnub 和 head.js

    有没有人成功整合过pubnub http www pubnub com 和 head js 正确吗 Pubnub http www pubnub com 希望我将他们的脚本放在页面底部并带有 div 就在它前面的标签 这可以确保在最后调用
  • 创建一个简单的 10 秒倒计时

    我想要一行这样写的 Your download will begin in 10 9 8 etc Beginning on page load seconds 我已经设置了 10 秒下载文本 并且我还查看了其他 stackoverflow
  • 在鼠标光标位置添加 cytoscape 节点

    我想在画布上的单击事件上的鼠标箭头位置添加一个 cytoscape 节点 我怎样才能做到这一点 我的方法 效果不太好 我可以通过单击创建一个节点 但无法确保创建的节点的位置位于我单击的位置 使用这样的东西 cy click function
  • 为什么 length 是 `Array` 的属性而不是 `Array.prototype` 链

    所以我在 V8 控制台上玩了很多 我做到了 Object getOwnPropertyNames 我期望得到 结果 然而 length 所以这意味着不是成为原型链的一部分 length是所有人的成员财产Array对象 这是一个错误 还是有任
  • 根据 Pandas 中的列表对多列进行排序

    感谢有关如何根据 pandas 中的倍数列表对给定多列进行排序的任何提示 如下所示 import pandas as pd sort a a d e sort b s1 s3 s6 sort c t1 t2 t3 df pd DataFra
  • 如何动态突出显示网页上的字符串?

    我想创建带有 url 的页面 例如 http xyzcorp schedules 2015Aug24 Aug28 Jim Hawkins http xyzcorp schedules 2015Aug24 Aug28 Billy Bones
  • 如何用javascript正确读取php cookies

    考虑这个 php 和 javascript 代码 然后我在控制台中看到的是 utma 111872281 291759993 1444771465 1445374822 1445436904 4 utmz 111872281 1444771
  • 无法实例化模块 [$injector:unpr] 未知提供程序:$routeProvider

    我从 AngularJS 升级时收到此错误1 0 7 to 1 2 0rc1 ngRoute 模块不再是核心的一部分angular js文件 如果您继续使用 routeProvider 那么您现在需要包括angular route js在你
  • 如何在 HTML / Javascript 页面中插入 PHP 下拉列表

    好吧 这是我的第二篇文章 请接受我是一个完全的新手 愿意学习 花了很多时间在各个网站上寻找答案 而且我几乎已经到达了我需要到达的地方 至少在这一点上 我有一个网页 其中有许多 javascript 函数 这些函数一起使用 google 地图
  • jQM / jquery-collagePlus 使用问题

    我正在使用 jQM 构建应用程序 并且尝试使用 jquery collagePlus http ed lea github io jquery collagePlus http ed lea github io jquery collage
  • ToggleClass 动画 jQuery?

    我的网站上有一个部分 当用户单击时我希望它展开 我正在使用 jQuerytoggleClass为了这 expandable function e e preventDefault this closest article toggleCla
  • 在 Fabric.js 中按宽度/高度在另一个画布对象内居中和缩放画布对象

    Goal 将一个对象 水平和垂直 置于另一个对象 矩形或组 的中心canvas via Fabric js或者通过Javascript保持原始对象的长宽比相同 但也不超过父对象的宽度 高度比例 父对象 矩形或组 不会居中于canvas元素
  • 如何处理requireJs超时错误?

    我正在使用 require js 作为加载框架编写一个移动混合应用程序 我遇到加载错误的问题 我想做的是在设备离线且无法下载在屏幕上显示地图所需的 google 地图 API 脚本时设置后备解决方案 我得到的只是 Uncaught Erro
  • 使用布尔值进行冒泡排序以确定数组是否已排序

    我有以下用于冒泡排序的代码 但它根本不排序 如果我删除布尔值那么它工作正常 我知道 由于我的 a 0 小于所有其他元素 因此没有执行交换 任何人都可以帮助我解决这个问题 package com sample public class Bub
  • Knockout.js 安全绑定

    我想使用带有淘汰赛的安全绑定 为此我使用敲除安全绑定 js https github com brianmhunt knockout secure binding 谁能解释一下为什么下面的代码不起作用 它会抛出一个错误 未捕获 淘汰 安全
  • JavaScript:测试与执行

    我想知道检查字符串 例如邮件 密码等 的最佳方法是什么 i exec a vs i test a exec返回值 test true test 1 way var mail req body mail if check mail exec
  • MongoDB中如何通过引用字段进行查询?

    我有两个 Mongo 模式 User id ObjectId name String country ObjectId Reference to schema Country Country id ObjectId name String
  • 强制输入数字小数位

    我想强制
  • Flowtype 属性“msg”缺失为 null 或未定义

    我发现 Flow 很难用 我明白那个Array find可以返回或未定义 因此 通过阅读以下内容 github Array find on Array 引发 https github com facebook flow issues 351

随机推荐

  • Android Studio 在创建新图像资源时不加载图像

    我正在尝试向 android studio 添加新的图像资源 并且已按照几个步骤正确添加它们 但 IDE 未加载图像 我已经关注了这些steps https i stack imgur com uJCIG gif 这是我的result ht
  • 无法将对象发送到 SOAP Web 服务

    我有一个肥皂网络服务 方法如下 string startReaction object reaction 在该方法中 我将此对象转换为其真实类型 Reaction reactionObj Reaction reaction 我有同样的Rea
  • Docker 与子目录组合并实时重新加载

    我使用创建了一个应用程序创建反应应用程序 https github com facebookincubator create react app并设置 docker compose 以设置容器并启动应用程序 当应用程序位于根目录时 应用程序
  • 正则表达式密码验证,OR 运算

    我需要使用以下规则验证密码 7 个字符 必须包含至少一个字母 必须包含至少一个数字或特殊字符 下面的正则表达式遵循 AND 操作 a z 0 9 7 这里如何执行第三条规则中的 OR 运算 我认为这个正则表达式会起作用 a z 0 9 7
  • Haxe + Webpack 导出空对象

    我正在尝试在 Haxe 编译器导出的 JS 上运行 webpack dev server 我正在使用 hxgenjs 库将 haxe 输出拆分为单独的模块 并尝试通过 webpack 合并它们 以使用热模块替换功能 一切似乎都正常 但输出是
  • Rails/Devise - 如何显示注册信息(不仅仅是编辑它)

    我今天安装了 Devise 到目前为止一切正常 devise 似乎唯一没有提供的是 registration show 操作 它显示用户信息 而不是注册编辑页面 我尝试覆盖注册控制器 但收到错误 未知操作 AbstractControlle
  • 将组总计添加到 Pandas 数据框中的最佳方法

    我有一个简单的任务 我想知道是否有更好 更有效的方法来完成 我有一个如下所示的数据框 Group Score Count 0 A 5 100 1 A 1 50 2 A 3 5 3 B 1 40 4 B 2 20 5 B 1 60 我想添加一
  • 从 PyPi 下载轮子

    如何从列出的软件包中下载特定的车轮PyPi https pypi python org pypi 我假设我会使用wget or curl 但我不确定要使用哪些参数 众所周知 PyPI 很难内省 幸运的是 Debian 项目用于扫描 FTP
  • 找出函数属于哪个模块

    在 ghci haskell 中 有一个命令可以告诉我函数属于哪个模块 在加载的模块中 例如如果该函数被称为whichMod 那么它将按如下方式工作 Prelude gt whichMod take Prelude Prelude gt w
  • 如何在 flutter 中使用进度指示器?

    我是颤振新手 想知道什么是更好的添加方法CircularProgressIndicator在我的布局中 例如 我的登录视图 该视图有用户名 密码和登录按钮 我确实想创建一个覆盖布局 用Opacity 在加载时 显示进度指示器 就像我在 Na
  • CDI 注入 POJO 何时应该起作用? (玻璃鱼 v3)

    当我将 EJB 3 1 beans 注入到 Inject 创建的 POJO 中时 注入就会起作用 当我自己构建 POJO 时 它不会 Glassfish v3 这是正确的行为吗 我的类 在 EJB 模块中 Singleton LocalBe
  • 为什么 Django 在测试期间不创建空白数据库?

    当我运行单元测试时 Django 1 6 似乎没有创建一个空白数据库来进行测试 我不明白为什么 姜戈docs http django readthedocs org en 1 6 topics testing overview html t
  • 在没有 UIWebView 的情况下播放 YouTube 链接的视频

    我想在我的应用程序中播放来自 YouTube 链接的视频 例如 http www youtube com watch v Uner 3tTY1I 但我不想将用户重定向到应用程序中的任何网络视图 只是想在我的应用程序的当前视图中的视频播放器中
  • 从 Python 访问/调用 Simulink

    我想在 Simulink 中对系统进行建模 然后从 python 程序访问该模拟以为其提供新的条件或输入 我知道有一个模块允许您从 Python 访问 Matlab 引擎 但这有点不同 我想要一个在 Simulink 中建模的系统 并使用
  • 当“参数列表太长”时,如何删除所有超过 3 天的文件?

    我有一个日志文件目录 其中包含 82000 个文件和目录 大约各半 我需要删除所有超过 3 天的文件和目录 在包含 37000 个文件的目录中 我可以使用以下命令执行此操作 find mtime 3 exec rm 但是对于 82000 个
  • 通过 EWS 为用户提供时区和工作时间

    是否可以通过EWS获取用户的时区和工作时间 我能够提取当前用户的 TZ 和工作时间 初始化 ExchangeService 的帐户 UserConfiguration usrConfig UserConfiguration Bind ser
  • vb.net返回多种类型的json对象?

    我需要从 Web 服务返回一些数据 如下所示 data page 1 data count 12883 data rows 0 id 1 data rows 0 name bob data rows 1 id 2 data rows 1 n
  • 在 C# 4.0 中,为什么方法中的输出参数不能是协变的?

    鉴于这个神奇的界面 public interface IHat
  • 特定嵌套属性的 MongoDB 投影

    data visits daily 2018 09 05 3586 2018 09 06 2969 2018 09 07 2624 2018 09 08 2803 2018 09 09 3439 2018 09 10 3655 我在 Mon
  • 对主干集合进行排序

    所需的功能 我正在使用 Backbone Collection 来查看可排序列表中的数据 我已经得到了单击某些 dom 元素会在我的 Collection 上设置属性的部分 以确定我想要排序的字段以及应该进行哪个方向的排序 然后应该在集合上