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

how to make child controllers within ng-repeat load one at a time?

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

在每个单元中,我都有一个子控制器,它根据父控制器的X&Y值准备要呈现的值。

目前,在处理整个事件之前,屏幕上不会呈现任何内容。

The behaviour I am after is that first the whole table is rendered showing only column header values and first cell values within each row. 然后让子控制器一次加载一个单元值…

非通缉行为的简化演示:https://jsfiddle.net/coolcatdev/xmtg3q31/1/

模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  <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">
       
          {{value}}
       
      </td>
    <tr>
  </table>

控制器:

1
2
3
4
5
6
7
8
9
10
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;
}

真实的东西:

模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  <script type="text/ng-template" id="comparison">
   
      Choose comparison table structure
     
     
     
     
     
     
     
     
     
      <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>
     
     
        <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">
             
                 
                   
                     
                   
                    <span style="clear:both;"></span>
                   
                     
                   
                 
             
            </td>
          </tr>
        </table>

控制器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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);
    }

}]);


下面是一个例子,说明如何使用$timeout执行此操作。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  <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">
       
          {{value}}
       
      </td>
    <tr>
  </table>

并使用myctrl2控制器中的计数,将时间与计数器相乘,使行依次呈现。

1
2
3
4
5
function MyCtrl2($scope, $timeout) {
        $timeout(function(){
         $scope.value = $scope.valX + $scope.valY;
    }, 100 * $scope.count);
}

举个例子