修改
创建了plnkr。
我有一个带有2个子对象的JSON字符串。
{
"ParentA":
{
...
},
"ParentB":
{
...
}
}
这两个对象都有子节点,ParentA中的一些子节点与ParentB中的某些子节点具有相同的名称。我希望在HTML中并排使用相同名称的对象,如下所示:
ParentA.Child1 ParentB.Child1
ParentA.Child2
ParentA.Child3 ParentB.Child3
如果有同名儿童,则将它们并排排列在同一条线上。如果没有来自ParentA的孩子与孩子姓名相同的孩子,那么只需显示ParentA孩子通常所在的空白空间。
ParentB是ParentA的子集,因此ParentB的子节点永远不会是ParentA的子节点。
我目前正在使用嵌套ng-repeats
和ng-if
来实现我想要的效果,但它会减慢页面的加载时间;对于ParentA的每个子节点,它遍历ParentB的每个子节点,直到找到匹配为止。
<div ng-controller="AppCtrl as appCtrl" flex="">
<div ng-controller="ClusterCtrl as modelCtrl">
<md-grid-list md-cols-sm="1" md-cols-md="2" md-cols-gt-md="6"
md-row-height-gt-md="1:1" md-row-height="4:3" md-gutter="8px"
md-gutter-gt-sm="4px" class="gridList" ng-repeat="clusterA in instances.ParentA.CLUSTERS">
<md-grid-tile md-rowspan="1" md-colspan="3" md-colspan-sm="1" class="gridTile">
<md-grid-tile-footer style="text-align:center;"><h3>{{clusterA.name}}</h3></md-grid-tile-footer>
</md-grid-tile>
<md-grid-tile ng-repeat="clusterB in instances.ParentB.CLUSTERS"
ng-if="clusterA.name == clusterB.name"
md-rowspan="1" md-colspan="3" md-colspan-sm="1" class="gridTile">
<md-grid-tile-footer style="text-align:center;"><h3>{{clusterB.name}}</h3></md-grid-tile-footer>
</md-grid-tile>
</md-grid-list>
</div>
</div>
我正在考虑在控制器中处理这个逻辑,但不知道如何实现它。
更新
我不认为我可以称之为进步,但无论如何我都会将其发布。加载DOM需要比以前长60ms,这不是很好;那是因为我在控制器中有3个循环,其中一个是嵌套的。然而,控制流逻辑已从视图中抽象出来并放入控制器中。
.controller('FlexClusterCtrl', ['$scope', 'ModelSvc', function($scope, ModelSvc) {
$scope.init = function() {
ModelSvc.getInstances().success(function(data) {
$scope.paNames = [];
$scope.pbNames = [];
$scope.joinedNames = new Array();
$scope.instances = data;
$scope.pa = data.pa;
$scope.pb = $scope.instances.pb;
angular.forEach($scope.pb.clusters, function(pbItem) {
$scope.paNames.push(pbItem.name);
});
console.log($scope.paNames);
angular.forEach($scope.wng.clusters, function(paItem) {
$scope.pbNames.push(paItem.name);
});
angular.forEach($scope.pbNames, function(paName) {
angular.forEach($scope.paNames, function(pbName) {
if(paName === pbName) {
var temp = paName;
$scope.joinedNames.push(temp);
$scope.joinedNames.push(temp);
}
});
if($scope.joinedNames.indexOf(paName) < 0) {
$scope.joinedNames.push(paName);
$scope.joinedNames.push(null);
}
});
console.log($scope.joinedNames);
});
};
$scope.init();
}]);
精简HTML,没有嵌套内容。
<div ng-controller="AppCtrl as appCtrl" flex="">
<div ng-controller="ClusterCtrl as modelCtrl">
<md-grid-list md-cols-sm="1" md-cols-md="2" md-cols-gt-md="2"
md-row-height-gt-md="3:1" md-row-height="4:3" md-gutter="8px"
md-gutter-gt-sm="4px" class="gridList" >
<md-grid-tile ng-repeat="cluster in joinedNames track by $index"
md-rowspan="1" md-colspan="1" md-colspan-sm="1" class="gridTile">
<md-grid-tile-footer style="text-align:center;"><h3>{{cluster}}</h3></md-grid-tile-footer>
</md-grid-tile>
</md-grid-list>
</div>
</div>
请注意,只有一个ng-repeat
和ng-if
。这就是我想要的,但我认为它会加快页面加载时间,根据Chrome的开发工具情况并非如此。我正在努力寻求更好的解决方案。该解决方案基本上只在控制器中创建了一个新的数据结构。它主要用于测试目的,看看我是否真的可以从视图中抽象控制逻辑;现在是时候更有效率地做到这一点了。
答案 0 :(得分:0)
我认为添加一个控制器方法只返回你需要的孩子并从ng-repeat中调用它,这样你就可以消除ng-if就可以了。
clusterB in instances.parent2.getKids(...)
不确定我是否足够好地遵循数据模型,也许这是不可能的。