我正在寻找一些帮助,将两个具有共同参考的对象逻辑地拟合到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`来监控objArr1
和objArr2
,因为我不知道这些会何时返回。
$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);
,错误消失了。但后来我不明白这会如何导致额外的摘要迭代。
最后,我想出的任何一种方法都存在一些问题。虽然第二种方法实际上正常工作并正确填充我的转发器,但控制台中存在令人讨厌的错误。
任何在此领域有更多经验的人都可以提供帮助。
我尝试使用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样式。
你有它。
答案 0 :(得分:1)
好的,我会尽力帮助。
我认为你的第二种方法的问题与this question有某种关系。阅读那里的评论。它可能与过滤器更改的列表有关。
至于你的第一种方法,我仍然不确定你要做什么,但我已经创建了this example来向你展示你可以在嵌套的ngRepeat
内进行过滤。
顺便说一句,如果您需要访问内部$index
内的ngRepeat
外部,则可以使用ngInit。