AngularJS Group By 指令没有外部依赖

标签 angularjs group-by angularjs-directive angularjs-ng-repeat ng-show

我是 Angular 的新手,想学习处理问题的最佳方法。我的目标是有一种可重用的方法来按标题创建组。我创建了一个可行的解决方案,但我认为这应该是一个指令,而不是我的 Controller 中的范围函数,但我不确定如何实现这一点,或者指令是否是正确的方法。任何输入将不胜感激。

查看我目前处理 jsFiddle 的方法

在 HTML 中,它是一个使用 ng-repeat 的简单列表,我在 ng-show 上调用我的 newGrouping() 函数。该函数传递对完整列表、我要分组的字段和当前索引的引用。

<div ng-app>
<div ng-controller='TestGroupingCtlr'>
    <div ng-repeat='item in MyList'>
        <div ng-show="newGrouping($parent.MyList, 'GroupByFieldName', $index);">
            <h2>{{item.GroupByFieldName}}</h2>
        </div>
        {{item.whatever}}
    </div>
</div>
</div>

在我的 Controller 中,我有我的 newGrouping() 函数,它只是将当前与前一个进行比较,除了第一项,并根据匹配返回 true 或 false。
function TestGroupingCtlr($scope) {

  $scope.MyList = [
    {GroupByFieldName:'Group 1', whatever:'abc'},
    {GroupByFieldName:'Group 1', whatever:'def'},
    {GroupByFieldName:'Group 2', whatever:'ghi'},
    {GroupByFieldName:'Group 2', whatever:'jkl'},
    {GroupByFieldName:'Group 2', whatever:'mno'}
  ];

  $scope.newGrouping = function(group_list, group_by, index) {
  if (index > 0) {
    prev = index - 1;
    if (group_list[prev][group_by] !== group_list[index][group_by]) {
      return true;
    } else {
      return false;
    }
  } else {
    return true;
  }
  };
}

输出将如下所示。

第一组
  • 美国广播公司
  • 定义

  • 第 2 组
  • jkl
  • 移动电话

  • 感觉应该有更好的方法。我希望这是一个我可以重用的通用实用程序功能。这应该是一个指令吗?有没有比我传递完整列表和当前索引的方法更好的方法来引用列表中的前一项?我将如何处理这个指令?

    任何意见是极大的赞赏。

    更新:寻找不需要外部依赖的答案。
    使用 underscore/lodash 或 angular-filter 模块有很好的解决方案。

    达里尔

    最佳答案

    如果您已经在使用 LoDash/Ununderscore 或任何函数库,您可以使用 执行此操作_.groupBy() (或类似名称)函数。

    在 Controller :

    var movies = [{"movieId":"1","movieName":"Edge of Tomorrow","lang":"English"},
                  {"movieId":"2","movieName":"X-MEN","lang":"English"},
                  {"movieId":"3","movieName":"Gabbar Singh 2","lang":"Telugu"},
                  {"movieId":"4","movieName":"Resu Gurram","lang":"Telugu"}];
    $scope.movies = _.groupBy(movies, 'lang');
    

    在模板中 :
    <ul ng-repeat="(lang, langMovs) in movies">{{lang}}
      <li ng-repeat="mov in langMovs">{{mov.movieName}}</li>
    </ul>
    

    这将呈现 :

    英语
  • 明日边缘
  • X战警

  • 泰卢固语
  • 加巴尔·辛格 2
  • 瑞苏·古拉姆


  • 更好的是,这也可以很容易地转换为过滤器,而无需太多样板代码来按属性对元素进行分组。

    更新:按多个键分组

    通常使用多个键进行分组非常有用。例如,使用 LoDash (source):
    $scope.movies = _.groupBy(movies, function(m) {
        return m.lang+ "-" + m.movieName;
    });
    

    更新为什么我推荐这种方法:
    ng-repeat 上使用过滤器/ng-options除非该过滤器快速执行,否则会导致严重的性能问题。谷歌过滤器性能问题。你会知道的!

    关于AngularJS Group By 指令没有外部依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19992090/

    相关文章:

    无法编译带有 ng-transclude 的 AngularJs 指令模板

    javascript - angularjs 选择下拉验证

    javascript - 加载所有内容后显示具有多个 ng-repeat 的表单

    javascript - 在 ng-if 中允许大写和小写

    python - 用 Pandas 将一行分成多个组

    javascript - 另一个元素发生变化时触发指令链接

    javascript - 如何在 AngularJS 中以正确的方式在指令中使用 ng-repeat

    html - 我如何在内存数据库中使用我的 Ionic 应用程序

    MySQL GROUP BY "and filter"

    mysql - 按自定义规则对值进行分组