AngularJS Group By Directive 没有外部依赖 [英] AngularJS Group By Directive without External Dependencies

查看:30
本文介绍了AngularJS Group By Directive 没有外部依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

查看我目前处理 jsFiddle

的方法

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

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

{{item.whatever}}

在我的控制器中,我有我的 newGrouping() 函数,它只是将当前与前一个进行比较,除了第一项,并根据匹配返回 true 或 false.

function TestGroupingCtlr($scope) {$scope.MyList = [{GroupByFieldName:'Group 1',随便:'abc'},{GroupByFieldName:'Group 1',随便:'def'},{GroupByFieldName:'Group 2',随便:'ghi'},{GroupByFieldName:'Group 2',随便:'jkl'},{GroupByFieldName:'Group 2',随便:'mno'}];$scope.newGrouping = function(group_list, group_by, index) {如果(索引> 0){上一个 = 索引 - 1;if (group_list[prev][group_by] !== group_list[index][group_by]) {返回真;} 别的 {返回假;}} 别的 {返回真;}};}

输出将如下所示.

第 1 组

  • abc
  • 定义

第 2 组

  • jkl
  • mno

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

非常感谢任何建议.

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

达里尔

解决方案

这是对上述 Darryl 解决方案的修改,允许多个按参数分组.此外,它利用 $parse 允许使用嵌套属性作为按参数分组.

使用多个嵌套参数的示例

http://jsfiddle.net/4Dpzj/6/

HTML

多个分组参数

<div ng-repeat="我列表中的项目 | orderBy:'groupfield' | groupBy:['groupfield', 'deep.category']"><h2 ng-show="item.group_by_CHANGED">{{item.groupfield}} {{item.deep.category}}</h2><ul><li>{{item.whatever}}</li>

过滤器(Javascript)

app.filter('groupBy', ['$parse', function ($parse) {返回函数(列表,group_by){var 过滤 = [];var prev_item = null;var group_changed = false;//这是一个新字段,它被添加到我们附加_CHANGED"的每个项目中//指示列表中的字段更改//是 var new_field = group_by + '_CHANGED';- JB 12/17/2013var new_field = 'group_by_CHANGED';//遍历列表中的每一项angular.forEach(列表,功能(项目){group_changed = 假;//如果不是第一项if (prev_item !== null) {//检查是否有任何 group by 字段更改//强制 group_by 进入数组group_by = angular.isArray(group_by) ?group_by : [group_by];//通过参数检查每个组for (var i = 0, len = group_by.length; i < len; i++) {如果 ($parse(group_by[i])(prev_item) !== $parse(group_by[i])(item)) {group_changed = 真;}}}//否则我们有列表中的第一项是新的别的 {group_changed = 真;}//如果组发生变化,则向项目添加一个新字段//表明这一点如果(group_changed){项目[新字段] = 真;} 别的 {项目[新字段] = 假;}过滤.推(项目);prev_item = 项目;});返回过滤;};}]);

I'm new to Angular and would like to learn the best way to handle a problem. My goal is to have a reusable means to create group by headers. I created a solution which works, but I think this should be a directive instead of a scope function within my controller, but I'm not sure how to accomplish this, or if a directive is even the right way to go. Any inputs would be greatly appreciated.

See my current approach working on jsFiddle

In the HTML it's a simple list using ng-repeat where I call my newGrouping() function on ng-show. The function passes a reference to the full list, the field I want to group by, and the current index.

<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>

In my controller I have my newGrouping() function which simply compares the current to the previous, except on the first item, and returns true or false depending upon a match.

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;
  }
  };
}

The output will look like this.

Group 1

Group 2

It feels like there should be a better way. I want this to be a common utility function that I can reuse. Should this be a directive? Is there a better way to reference the previous item in the list than my method of passing the full list and the current index? How would I approach a directive for this?

Any advice is greatly appreciated.

UPDATE: Looking for an answer that does not require external dependencies. There are good solutions using underscore/lodash or the angular-filter module.

Darryl

解决方案

This is a modification of Darryl's solution above, that allows multiple group by parameters. In addition it makes use of $parse to allow the use of nested properties as group by parameters.

Example using multiple, nested parameters

http://jsfiddle.net/4Dpzj/6/

HTML

<h1>Multiple Grouping Parameters</h1>
<div ng-repeat="item in MyList  | orderBy:'groupfield' | groupBy:['groupfield', 'deep.category']">
    <h2 ng-show="item.group_by_CHANGED">{{item.groupfield}} {{item.deep.category}}</h2>
     <ul>
        <li>{{item.whatever}}</li>
     </ul>
</div>  

Filter (Javascript)

app.filter('groupBy', ['$parse', function ($parse) {
    return function (list, group_by) {

        var filtered = [];
        var prev_item = null;
        var group_changed = false;
        // this is a new field which is added to each item where we append "_CHANGED"
        // to indicate a field change in the list
        //was var new_field = group_by + '_CHANGED'; - JB 12/17/2013
        var new_field = 'group_by_CHANGED';

        // loop through each item in the list
        angular.forEach(list, function (item) {

            group_changed = false;

            // if not the first item
            if (prev_item !== null) {

                // check if any of the group by field changed

                //force group_by into Array
                group_by = angular.isArray(group_by) ? group_by : [group_by];

                //check each group by parameter
                for (var i = 0, len = group_by.length; i < len; i++) {
                    if ($parse(group_by[i])(prev_item) !== $parse(group_by[i])(item)) {
                        group_changed = true;
                    }
                }


            }// otherwise we have the first item in the list which is new
            else {
                group_changed = true;
            }

            // if the group changed, then add a new field to the item
            // to indicate this
            if (group_changed) {
                item[new_field] = true;
            } else {
                item[new_field] = false;
            }

            filtered.push(item);
            prev_item = item;

        });

        return filtered;
    };
}]);

这篇关于AngularJS Group By Directive 没有外部依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆