4

我有一个非常简单的场景,其中有一组记录可用,我需要在一个简单的 ng-repeat 中显示它们。但是,我需要按属性分组的记录,而我的目标不是不必更改集合即可完成此分组。我的想法是可以应用某种类型的过滤器,但实际上过滤器、过滤器、数据和不分组。有没有办法收集并简单地分组和重复?

真正的 hack-ish jsFiddle 就在这里,我正在尝试做。

http://jsfiddle.net/bryangrimes/RufQh/5/

简而言之,这个想法是这样的:

<ul>
      <li ng-repeat="log in logs grouped by log.dept">
        <h4>{{log.dept}}</h4>
        {{log.name}} worked {{log.hours}} this week
      </li>            
  </ul>

更新:所以最后我们已经使用 taffyDB 来容纳原始数据集,所以它只是被扩展了。

$.each($scope.logs, function() {
        var log = $(this)[0];

        // build angular friendly data structure
        log.workLogsDB = TAFFY(log.worklogs);
        log.deptLogs   = [];

        $.each(log.workLogsDB().distinct('department').sort(), function() {
            var dept  = $(this)[0].toString();
            var cost  = log.workLogsDB({department:dept}).sum('cost');
            var hours = log.workLogsDB({department:dept}).sum('hours');
            var items = log.workLogsDB({department:dept}).get();

            log.deptLogs.push({
                department: dept,
                total_cost: cost,
                total_hours: hours,
                line_items: items
            });
        });
    });

和要呈现的 HTML:

<div ng-repeat="log in logs">
                <h3 onclick="$('#{{log.project}}').slideDown()">    
                    {{log.project}} hours:{{log.hours}} cost: ${{log.cost}}
                </h3>
                <ul id="{{log.project}}" style="display: none;">
                    <div ng-repeat="log in log.deptLogs">
                        <span style="font-weight: bold; text-transform: capitalize;">{{ log.department }} - Team Cost: ${{ log.total_cost }}, Team Hours: {{ log.total_hours }} </span>
                        <li ng-repeat="line in log.line_items">
                            {{line.employee}} {{line.hours}} hours
                        </li>
                        <br>
                    </div>
                </ul>
            </div>
4

3 回答 3

7

我认为您需要创建该集合的排序副本,然后对该排序集合进行 ng-repeat。这是我不久前写的一个小提琴,当时有人问了类似的问题。要点:

function MyCtrl($scope, orderByFilter) {  // inject orderByFilter
   $scope.sortedLogs = orderByFilter($scope.logs, '+dept');
}

HTML:

<ul>
  <li ng-repeat="log in sortedLogs">
      <ng-switch on="$first || log.dept != sortedLogs[$index-1].dept">
          <div ng-switch-when="true" class="group"><h4>{{log.dept}}</h4>
      </ng-switch>
      {{log.name}} worked {{log.hours}} this week
  </li>
</ul>
于 2012-12-28T21:49:40.877 回答
1

我喜欢马克的回答,我的策略通常是重新调整集合以使渲染更容易。

这是一个显示该方法的小提琴http://jsfiddle.net/RufQh/12/

var sorted = [];
logs.forEach(function(log){if (!sorted[log['dept']]) {sorted[log['dept']]= []} sorted[log['dept']].push(log);})

$scope.depts=[];
for(var dept in sorted) {
    $scope.depts.push({name:dept,items:sorted[dept]});
}

一旦我有了这个,我就会用嵌套循环渲染

<li ng-repeat="dept in depts">{{dept.name}}<br/> 
          <ul>
              <li ng-repeat="log in dept.items">{{log.name}} worked {{log.hours}} this week as a(n) {{log.dept}}</li>
          </ul>
  </li>

使用 map/reduce 或 taffyBD 之类的框架可以更轻松地转换数据。这种方法的缺点是多次遍历数据(而不是单次排序)和添加角度范围的创建。

好处是它可能更容易呈现内容,因为它是在控制器中组织的。

于 2012-12-30T13:57:41.920 回答
0

您已经在使用 taffydb 来获取数据,因此它可能与您无关,但其他想要这样做的人可能会发现 ForerunnerDB ( http://www.forerunnerdb.com ) 很有用,因为它具有类似 MongoDB 的高级查询,而且支持数据视图,以便您可以通过查询过滤集合并从中生成视图。

视图包含来自底层集合的最新过滤数据,如果集合上的数据发生更改,视图也会自动更新。

于 2015-02-05T13:06:19.073 回答