如何避免在表格中使用多个ngRepeat时出现多个tbody

3

演示: http://jsfiddle.net/6dJ79/1/

上面的演示可以工作,但它通过重复tbody来实现结果。我想避免这种情况。

有没有其他方法可以让每个人的每种颜色都有一行,而不需要重复tbody?理想情况下,我希望输出看起来像下面这样,而不需要操作数据:

<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Color</th>
            <th>Fav</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Bill</td>
            <td>red</td>
            <td>yes</td>
        </tr>
        <tr>
            <td>Bill</td>
            <td>blue</td>
            <td>no</td>
        </tr>
        <tr>
            <td>Larry</td>
            <td>purple</td>
            <td>yes</td>
        </tr>
        <tr>
            <td>Larry</td>
            <td>yellow</td>
            <td>no</td>
        </tr>
    </tbody>
</table>

数据:
{
    name: 'Bill',
    colors: [{
        name: 'red',
        favColor: 'yes'
    }, {
        name: 'blue',
        favColor: 'no'
    }]
}, {
    name: 'Larry',
    colors: [{
        name: 'purple',
        favColor: 'yes'
    }, {
        name: 'yellow',
        favColor: 'no'
    }]
}

由于您坚持使用<table>,您唯一的真正选择是将数据展平或在HTML中解开内部集,使用ng-repeat-startng-repeat-end。但在这种情况下,这意味着所有的“人”必须拥有相同的“颜色”(当然不是相同的答案)。 - Norguard
2个回答

2

这里有一个使用过滤器的实现

myApp.filter('denormalize', function(){
    return function(people) {
        var arr = [];
        angular.forEach(people, function(person){
            angular.forEach(person.colors, function(color){
                arr.push({
                    name: person.name, 
                    color: color.name, 
                    fav: color.favColor
                });
            });
        });

        return arr;
    }
});

在HTML中:

<tbody>
    <tr ng-repeat="person in people | denormalize">
        <td>{{ person.name }}</td>
        <td>{{ person.color }}</td>
        <td>{{ person.fav }}</td>
    </tr>
</tbody>

1
这个和Brocco的回答似乎都有infdig问题;http://docs.angularjs.org/error/$rootScope/infdig当它作为控制器时,我可以通过仅填充一次数组来解决它,但是我们如何在过滤器中实现这一点呢? - JasonF

1

我会在您的作用域中创建一个函数,使用嵌套循环将嵌套对象展平为简单的一维数组。

这是一个可工作的 fiddle 作用域方法:

$scope.peopleColors = function () {
    var pc = [];
    for (var i = 0, plen = $scope.people.length; i < plen; i++) {
        var person = $scope.people[i];
        for (var j = 0, clen = person.colors.length; j < clen; j++) {
            var color = person.colors[j];
            pc.push({
                name: person.name,
                color: color.name,
                favColor: color.favColor
            });
        }
    }
    return pc;
};

标记:

<tr ng-repeat="pc in peopleColors()">

编辑:我更新了fiddle,展示了动态添加新人的功能。


1
这是一个很好的解决方案,但是却存在infdig问题。为了避免infdig,变量pc需要在peopleColors()之外进行初始化和创建。不过理想情况下我更倾向于将其作为一个过滤器,只是不确定是否可以通过过滤器来解决infdig问题。http://docs.angularjs.org/error/$rootScope/infdig - JasonF

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接