我是Angular的新手,我想学习处理问题的最佳方法。我的目标是要有一种可重复使用的方式来创建标题组。我创建了一个可行的解决方案,但我认为这应该是指令,而不是控制器中的作用域函数,但是我不确定如何实现此目标,或者不确定指令是否正确。任何输入将不胜感激。
看到我目前在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>
在我的控制器中,我有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组
感觉应该有更好的方法。我希望这是我可以重用的通用实用程序功能。这应该是指令吗?有比我传递完整列表和当前索引的方法更好的方法来引用列表中的上一项吗?为此,我将如何处理指令?
任何意见是极大的赞赏。
更新:寻找不需要外部依赖项的答案。使用下划线/破折号或角度过滤器模块有很好的解决方案。
达里尔
这是对以上Darryl解决方案的修改,它允许使用多个by group参数。另外,它使用$ parse允许将嵌套属性用作按参数分组。
使用多个嵌套参数的示例
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>
过滤器(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; }; }]);