如何让ng-repeat中的子控制器一次加载一个?

时间:2017-04-04 08:52:45

标签: javascript angularjs

我有一个主控制器,它获取表示表格(行和列)的x和y坐标的数据。

在每个单元格中,我有一个子控制器,它准备基于x和amp; y父控制器的值。

此时屏幕上没有任何内容呈现,直到处理完所有内容。

我所追求的行为是,首先渲染整个表,仅显示列标题值和每行中的第一个单元格值。并且让子控制器一次加载一个单元格值......

非想要行为的简化演示: https://jsfiddle.net/coolcatDev/xmtg3q31/1/

模板:

<div ng-controller="MyCtrl">
  <table class="table-bordered">
    <tr>
      <th>Y/X</th>
      <th ng-repeat="valX in x">{{valX}}</th>
    <tr>
    <tr ng-repeat="valY in y">
      <td>{{valY}}</td>
      <td ng-repeat="valX in x">
        <div ng-controller="MyCtrl2">
          {{value}}
        </div>
      </td>
    <tr>
  </table>
</div>

控制器:

var myApp = angular.module('myApp',[]);

function MyCtrl($scope) {
    $scope.x = ['a','b','c','d','e','f','g'];
    $scope.y =      ['1','2','3','4','5','6','7','8','9','10','1','2','3','4','5','6','7','8','9','10','1','2','3','4','5','6','7','8','9','10','1','2','3','4','5','6','7','8','9','10','1','2','3','4','5','6','7','8','9','10','1','2','3','4','5','6','7','8','9','10','1','2','3','4','5','6','7','8','9','10'];
}

function MyCtrl2($scope) {
    $scope.value = $scope.valX + $scope.valY;
}

真实的事情:

模板:

  <script type="text/ng-template" id="comparison">
    <div ng-controller="comparisonController" class="container-fluid">
      <h3>Choose comparison table structure</h3>
      <div class="multiDropMenus" ng-dropdown-multiselect="" options="colXoptions" selected-model="colXoptionsModel" translation-texts="xBtnLabel" extra-settings="settingsXaxisBtn" events="updateModelX">
      </div>
      <div class="multiDropMenus" ng-dropdown-multiselect="" options="colYoptions" selected-model="colYoptionsModel" translation-texts="yBtnLabel" extra-settings="settingsYaxisBtn" events="updateModelY">
      </div>
      <div class="multiDropMenus" ng-dropdown-multiselect="" options="colValueoptions" selected-model="colValueoptionsModel" translation-texts="valueBtnLabel" extra-settings="settingsValueaxisBtn" events="updateModelV">
      </div>
      <div class="multiDropMenus" ng-dropdown-multiselect="" options="colGroupingoptions" selected-model="colGroupingoptionsModel" translation-texts="groupingBtnLabel" extra-settings="settingsGroupingaxisBtn" events="updateModelG">
      </div>
      <br>
      <button ng-if="colXoptionsModel && colYoptionsModel && colValueoptionsModel && colGroupingoptionsModel" ng-click="createTable()" type="button" class="btn btn-default btn-sm col-xs-12"><span class=""></span> Create table</button>
      <br>
      <div class="container-fluid" style="overflow-x:scroll;">
        <table ng-if="tableReady" class="table-bordered" style="width:100%;overflow-x:scroll;">
          <tr>
            <th>{{colYoptionsModel.attobj.name}}/{{colXoptionsModel.attobj.name}}</th>
            <th ng-repeat="x in uniqueX" ng-init="colHeader = x.get4(colXoptionsModel.key)[0].attributes.displayName[0] || x.get4(colXoptionsModel.key).toString()">
              {{colHeader}}
            </th>
          </tr>
          <tr ng-repeat="y in uniqueY" ng-init="rowIndex = y.get4(colYoptionsModel.key)[0].attributes.displayName[0] || y.get4(colYoptionsModel.key).toString()">
            <td>{{rowIndex}}</td>
            <td ng-repeat="x in uniqueX">
              <div ng-controller="comparisonValues">
                  <div ng-repeat="dbo in cellValues">
                    <div ng-if="grouping" ng-init="attobj = colGroupingoptionsModel; key = attobj.key; values=dbo.get4(attobj.key); template = attobj.template || getAttributeTemplate(dbo.clazz + attobj.key);">
                      <div class="contentDecompressed" customtemp></div>
                    </div>
                    <span style="clear:both;"></span>
                    <div ng-init="attobj = colValueoptionsModel; key = attobj.key; values=dbo.get4(attobj.key); template = attobj.template || getAttributeTemplate(dbo.clazz + attobj.key);">
                      <div class="contentDecompressed" customtemp></div>
                    </div>
                  </div>
              </div>
            </td>
          </tr>
        </table>
      </div>
    </div>
  </script>

控制器:

app.controller('comparisonValues', ['$scope',
  function ($scope) {
        console.log('loading cell');
        //filter allDBOS where xmodel col = x and ymodel col = y
        var checkX = $scope.x.get4($scope.colXoptionsModel.key)[0].cid || $scope.x.get4($scope.colXoptionsModel.key).toString();
        var checkY = $scope.y.get4($scope.colYoptionsModel.key)[0].cid || $scope.y.get4($scope.colYoptionsModel.key).toString();

        $scope.cellValues = _.filter($scope.allDBOS, function(dbo){ 
          var checkDboX = dbo.get4($scope.colXoptionsModel.key)[0].cid || dbo.get4($scope.colXoptionsModel.key).toString();
          var checkDboY = dbo.get4($scope.colYoptionsModel.key)[0].cid || dbo.get4($scope.colYoptionsModel.key).toString(); 

          if(checkDboX == checkX && checkDboY == checkY){
            return dbo;
          }
        });
        if($scope.cellValues.length > 1){
          $scope.grouping = true;
        }
        $scope.compressed=false;

}]);

app.controller('comparisonController', ['$scope', '$location', '$http', '$q', 'templateService',
  function ($scope, $location, $http, $q, templateService) {
    $scope.getAttributeTemplate = templateService.getAttributeTemplate;

    $scope.tableReady = false;
    $scope.compare.val = false;

    $scope.colXoptions = $scope.columns;
    $scope.colXoptionsModel={}
    $scope.settingsXaxisBtn = {closeOnSelect:true, displayProp: 'key', idProp: 'key', externalIdProp:'', selectionLimit: 1, buttonClasses:'graphDropDowns', smartButtonMaxItems: 1, showUncheckAll:false, showCheckAll:false};
    $scope.xBtnLabel = {buttonDefaultText:'X-Axis'};
    $scope.updateModleX = {
      onItemSelect: function(item) { 
        $scope.updateModleX = $scope.updateModleX;
      },
      onItemDeselect: function(item) { 
       $scope.updateModleX = {};

      }
    };

    $scope.colYoptions = $scope.columns;
    $scope.colYoptionsModel={}
    $scope.settingsYaxisBtn = {closeOnSelect:true, displayProp: 'key', idProp: 'key', externalIdProp:'', selectionLimit: 1, buttonClasses:'graphDropDowns', smartButtonMaxItems: 1, showUncheckAll:false, showCheckAll:false};
    $scope.yBtnLabel = {buttonDefaultText:'Y-Axis'};
    $scope.updateModleY = {
      onItemSelect: function(item) { 
        $scope.colYoptionsModel = $scope.colYoptionsModel;
      },
      onItemDeselect: function(item) { 
       $scope.colYoptionsModel = {};

      }
    };

    $scope.colValueoptions = $scope.columns;
    $scope.colValueoptionsModel={}
    $scope.settingsValueaxisBtn = {closeOnSelect:true, displayProp: 'key', idProp: 'key', externalIdProp:'', selectionLimit: 1, buttonClasses:'graphDropDowns', smartButtonMaxItems: 1, showUncheckAll:false, showCheckAll:false};
    $scope.valueBtnLabel = {buttonDefaultText:'Value-Axis'};
    $scope.updateModleV = {
      onItemSelect: function(item) { 
        $scope.colValueoptionsModel = $scope.colValueoptionsModel;
      },
      onItemDeselect: function(item) { 
       $scope.colValueoptionsModel = {};

      }
    };

    $scope.colGroupingoptions = $scope.columns;
    $scope.colGroupingoptionsModel={}
    $scope.settingsGroupingaxisBtn = {closeOnSelect:true, displayProp: 'key', idProp: 'key', externalIdProp:'', selectionLimit: 1, buttonClasses:'graphDropDowns', smartButtonMaxItems: 1, showUncheckAll:false, showCheckAll:false};
    $scope.groupingBtnLabel = {buttonDefaultText:'Grouping-Axis'};
    $scope.updateModleG = {
      onItemSelect: function(item) { 
        $scope.colGroupingoptionsModel = $scope.colGroupingoptionsModel;
      },
      onItemDeselect: function(item) { 
       $scope.colGroupingoptionsModel = {};

      }
    };

    //get all dbos from query without pagination
    $scope.createTable = function(){
      $scope.tableReady=false;
      $scope.query2 = angular.copy($scope.queryObj);
      var url = '/api/list2/json/' + $scope.class;
      $scope.query2.count = 0;
      $scope.query2.page = 1;

      var len = url.length + JSON.stringify($scope.query2).length + $location.url().length;
      var prom = (len > 2000)
        ? $http.post(url, {'q':JSON.stringify($scope.query2), 'hashfragment' : $location.url()}, {transformResponse: transformResponse})
        : $http.get(url, {cache:true, params:{"q":JSON.stringify($scope.query2)}, headers:{'hashfragment':$location.url()}, transformResponse: transformResponse});
      prom.then(
        function (response) {
            $scope.allDBOS = response.data.data.requested;
            console.log('alldbos');
            console.log($scope.allDBOS.length);
            $scope.getUniqueXY();
        },
        function (response) {
          // console.log('response failed to load');
      });

      return prom;     
    }

    //get distinct values for allDBOS.x and allDBOS.y model to use as table col headers(x) and table row indexes(y)
    $scope.getUniqueXY = function(){
      $scope.uniqueX = _.uniq($scope.allDBOS, function(dbo) { 
        return dbo.get4($scope.colXoptionsModel.key)[0].cid || dbo.get4($scope.colXoptionsModel.key).toString();   
      });     

      $scope.uniqueY = _.uniq($scope.allDBOS, function(dbo) { 
        return dbo.get4($scope.colYoptionsModel.key)[0].cid || dbo.get4($scope.colYoptionsModel.key).toString();   
      });
      // console.log('unique x vals in dbos');
      // console.log($scope.uniqueX.length);
      // console.log('unique y vals in dbos');
      // console.log($scope.uniqueY.length);

      //table starts to render nad directive for each cell kicks in: app.directive('loadComparisonValues'...
      $scope.tableReady = true; 
      console.log($scope.tableReady);
    }

}]);

1 个答案:

答案 0 :(得分:1)

以下是使用$timeout

执行此操作的示例

首先,通过添加计数来跟踪视图中的当前行

"index_exclude_patterns": ["*.log", "node_modules/*", "vendor/*"]

并使用MyCtrl2控制器中的计数通过将时间与计数器相乘来使行相互渲染

<div ng-controller="MyCtrl">
  <table class="table-bordered">
    <tr>
      <th>Y/X</th>
      <th ng-repeat="valX in x">{{valX}}</th>
    <tr>
    <tr ng-repeat="valY in y" ng-init="count = $index;">
      <td>{{valY}}</td>
      <td ng-repeat="valX in x">
        <div ng-controller="MyCtrl2">
          {{value}}
        </div>
      </td>
    <tr>
  </table>
</div>

这里是example