将多个相关数据集拟合到AngualrJs ngRepeat

时间:2015-07-08 09:33:28

标签: javascript angularjs

我正在寻找一些帮助,将两个具有共同参考的对象逻辑地拟合到AngularJs ngRepeat中。

示例对象(这些对象从服务中调用):

$scope.objArr1 = [
    { id: 1, Name: 'Name 1', Value: 'Value 1', },
    { id: 2, Name: 'Name 3', Value: 'Value 2', },
    { id: 3, Name: 'Name 3', Value: 'Value 3', },
];

$scope.objArr2 = [
    { id: 1, Name: 'Name 1', Value: 'Value 1', ObjArr1: { id: 1, Name: 'Name 1', Value: 'Value 1', }, },
    { id: 2, Name: 'Name 1', Value: 'Value 1', ObjArr1: { id: 1, Name: 'Name 1', Value: 'Value 1', }, },
    { id: 3, Name: 'Name 1', Value: 'Value 1', ObjArr1: { id: 3, Name: 'Name 3', Value: 'Value 3', }, },
];

这些方面的东西。基本上如果你能这样想的话;第一个数组对象形成桶,而第二个数组对象形成适合相应桶的项。

第一种方法

HTML:

<ul>
    <li data-ng-repeat="item in objArr1 | filter : someFilter">{{item.Name}}
        <ul>
            <!-- how to filter objArr2 items based on objArr1 property ? -->
            <li data-ng-repeat="item2 in objArr2 | filter : someOtherFilter">{{item2.Name}}</li>
        </ul>
    </li>
</ul>

简单来说,我试图过滤内部转发器中与当前转发器$scope.objArr2对应的item项。我使用someOtherFilter尝试了各种各样的事情,但我无法从外部转发器引用item

问题

我无法弄清楚如何让这个过滤位工作。

第二种方法

当所有其他方法都失败时,我决定将数据结构合并为一个:

// deep copy to avoid dependency
angular.copy($scope.objArr1, $scope.objArr3);
// loop over objArr3 and add empty array objArr2
// which we will populate a bit later
angular.forEach($scope.objArr3, function (val, key) {
    $scope.objArr3[key]["objArr2"] = [];
});

然后我设置$watch - er`来监控objArr1objArr2,因为我不知道这些会何时返回。

$scope.$watchGroup(['objArr1', 'objArr2'], function (newVals, oldVals) {
    // check to make sure there is stuff to loop over
    // i am wrongly assuming there will be items in both objArr1 and objArr2
    // i'll worry about what to do when there is no data a bit later
    if(newVals[0].length > 0 && newVals[1].length > 0) {
        angular.forEach($scope.objArr1, function (val1, key1) {
            angular.forEach($scope.objArr2, function (val2, key2) {
                 if (val1.Id === val2.objArr1.Id) {
                     $scope.objArr3[key1].objArr2.push(val2);
                 }
            });
        });
    }
});

HTML:

<ul>
    <li data-ng-repeat="item in objArr1 | filter : someFilter">{{item.Name}}
        <ul>
            <li data-ng-repeat="item2 in item.objArr2">{{item2.Name}}</li>
        </ul>
    </li>
</ul>

问题

虽然这在表面上运行得很好但我在控制台中得到了一个可爱的Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!

我有点疑惑是什么导致$ digest多次开火。

但是,通过评论我的观察者的更新行$scope.objArr3[key1].objArr2.push(val2);,错误消失了。但后来我不明白这会如何导致额外的摘要迭代。

HALP

最后,我想出的任何一种方法都存在一些问题。虽然第二种方法实际上正常工作并正确填充我的转发器,但控制台中存在令人讨厌的错误。

任何在此领域有更多经验的人都可以提供帮助。

更新

我尝试使用someOtheFilter时遇到的一些愚蠢的事情是:

data-ng-repeat="item2 in objArr2 | filter : someOtherFilter"
$scope.someOtherFilter = function(item){
    // item is always the current inner repeaters item2 object
    // that just the way angular filter works
    return item.objArr2 === $scope.objArr1.Id; // this is silly but idea is there
};

data-ng-repeat="item2 in objArr2 | filter : someOtherFilter(item)"
$scope.someOtherFilter = function(item){
    // if memory serves me right
    // in this case item is always repeaters current item2 object
    // with no ability to reference outer repeaters current item object
}

data-ng-repeat="item2 in objArr2 | filter : someOtherFilter(item, item2)"
$scope.someOtherFilter = function(item, item2) {
    // if memory serves me right
    // in this case item was always inner repeaters current item2 object
    // and item2 is always undefined
    // again with no ability to reference outer repeaters current item
}

此时我放弃了第一种方法。但是现在考虑一下我可能已经能够利用$index(如果内部转发器以某种方式或其他方式没有覆盖外部转发器$index引用)来获取外部转发器的索引值并尝试得到$scope.objArr1[index]

无论哪种情况适用于someOtherFilter内部工作,只需要将内部对象objArr1.Id与外部对象Id进行比较。

更新(从我的错误中吸取教训)

好的,确认答案正常后,我的制作示例Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!中仍有同样的问题。

冷却几天后,我决定重新审视这个问题,这就是我找到的。

<div class="block" data-ng-repeat="team in Teams | filter : validateAgeCategory">
    <div data-ng-style="getHeaderStyle()">
        <span>{{team.Name}}</span>
        <!-- bunch of things removed for brevity -->
    </div>
    <ul data-ng-style="getListStyle()">
        <li data-ng-repeat="players in Players | filter : { Team: { Id: team.Id, }, }">
            <a data-ng-style="getListItemStyle()" data-ng-href="#/players/{{player.Id}}">{{player.Name}}</a>
        </li>
    </ul>
</div>

我调整了我的团队/播放器示例以便于理解。无论如何,在生产中我使用一些ng-style调用来检索CSS。

我这样做的原因是因为IE在文档加载期间倾向于从内联{{}}定义中删除style="color: {{color}};"定义。它可以说是IE的错误。

继续前进,我发现最里面的ng-style导致了$ digest的错误。删除data-ng-style="getListItemStyle()"一切都很愉快。当然,一切都是我的。

将此视为开销,最好创建CSS类,然后根据某些索引应用类来设置HTML样式。

你有它。

1 个答案:

答案 0 :(得分:1)

好的,我会尽力帮助。

我认为你的第二种方法的问题与this question有某种关系。阅读那里的评论。它可能与过滤器更改的列表有关。

至于你的第一种方法,我仍然不确定你要做什么,但我已经创建了this example来向你展示你可以在嵌套的ngRepeat内进行过滤。

顺便说一句,如果您需要访问内部$index内的ngRepeat外部,则可以使用ngInit