AngularJS: выравнивание элементов из разных ng-повторов

0

РЕДАКТИРОВАТЬ:

Создал plnkr.

У меня есть строка JSON с двумя дочерними объектами.

{
   "ParentA":
   { 
      ...
   },
   "ParentB":
   {
      ...
   }
}

У обоих этих объектов есть дети, а некоторые из детей в ParentA имеют то же имя, что и некоторые из детей в ParentB. Я хочу выровнять объекты с тем же именем бок о бок в моем HTML, например:

ParentA.Child1    ParentB.Child1
ParentA.Child2
ParentA.Child3    ParentB.Child3

Если есть дети с тем же именем, то выровняйте их бок о бок в одной строке. Если в ParentA отсутствует дочерний объект с тем же именем, что и дочерний, тогда просто отобразите дочерний элемент ParentA с пустым пространством, где обычно будет ParentB.

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 занимает 60 мс дольше, чем раньше, что не очень хорошо; это потому, что у меня есть 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 dev. Я буду работать над лучшим решением. Это решение просто создало новую структуру данных в контроллере. Это было главным образом для целей тестирования, чтобы увидеть, могу ли я фактически абстрагировать логику управления с точки зрения; теперь самое время сделать это более эффективно.

  • 0
    альтернатива будет отображать весь новый массив перед отправкой для просмотра. Создать демо с примерами данных
  • 0
    Работаю над написанием программы для переформатирования моей строки JSON, чтобы в будущем я мог использовать ее на SO без передачи конфиденциальных данных. Я отправлю обратно сюда, когда все будет готово.
Показать ещё 1 комментарий
Теги:

1 ответ

0

Я бы подумал о добавлении метода контроллера, который просто возвращает нужные вам дети и вызывая его из вашего ng-repeat, так что вы можете устранить ng-if, если бы сделали трюк.

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

Не уверен, что я достаточно хорошо слежу за моделью данных, возможно, это невозможно.

  • 0
    Да, я работаю над абстрагированием логики управления от представления в контроллер. Я до сих пор не понял, как я получу все, что я хочу, от одного нг-повтора. Если дочерний элемент parentA имеет то же имя, что и дочерний элемент parentB, я хочу, чтобы эти дочерние элементы отображались рядом. Когда это не так (то есть, когда в parentA или parentB есть уникальный дочерний элемент), я хочу, чтобы было пустое место, где обычно находился бы соответствующий дочерний элемент. Я обновил PLNKR, чтобы визуально показать, что я хочу. Я хочу сохранить визуальные эффекты такими же, но абстрагировать логику управления от представления в Ctrl.
  • 0
    Это интересный вызов. Пожалуйста, отправьте свое решение после того, как вы прибили его!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню