AngularJS:对齐不同ng-repeats的元素

时间:2015-10-05 20:04:56

标签: angularjs

修改

创建了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-repeatsng-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-repeatng-if。这就是我想要的,但我认为它会加快页面加载时间,根据Chrome的开发工具情况并非如此。我正在努力寻求更好的解决方案。该解决方案基本上只在控制器中创建了一个新的数据结构。它主要用于测试目的,看看我是否真的可以从视图中抽象控制逻辑;现在是时候更有效率地做到这一点了。

1 个答案:

答案 0 :(得分:0)

我认为添加一个控制器方法只返回你需要的孩子并从ng-repeat中调用它,这样你就可以消除ng-if就可以了。

clusterB in instances.parent2.getKids(...) 

不确定我是否足够好地遵循数据模型,也许这是不可能的。