2016-07-17 14 views
5

私は最近ngTableDynamicディレクティブを使用していました。しかし、私のテーブルが本当にダイナミックなときに問題にぶつかりつつ、予想するカラムの数やタイプをあらかじめ知っていません。私が知っている列を宣言し、私の​​コントローラの上部に約束の結果に基づいて動的なngテーブルにカラムを追加

は、すべてのテーブルに存在することになる。

$scope.columns = [ 
    { title: 'ID', field: 'id', visible: true, required: true }, 
    { title: 'Email', field: 'email', visible: true, required: true } 
]; 

私はその結果を返すサービスへの非同期呼び出しを行います。これらの結果に基づいて、私は$scope.columnsに任意の追加の列オブジェクトをプッシュする:

var getResults = function() { 
    var defer = $q.defer(); 
    reportService.getReportResults({ 
    report: $scope.id, 
    version: $scope.version 
    }).$promise.then(function(data) { 
    $scope.data = data.results; 
    _.each($scope.data[0], function(value, key) { 
     if (key !== 'id' && key !== 'email') { 
     $scope.columns.push({ 
      title: _str.capitalize(key), 
      field: key, 
      visible: true, 
      required: false 
     }); 
     } 
    }); 
    defer.resolve($scope.data); 
    }); 
    return defer.promise; 
}; 

しかし、列は、私は、ブラウザで表示するとき、私のテーブルにそれを作ることはありません_.each内に押され。しかし私は、列が追加されたデータのセットの例のハードコーディングされたモックと私の非同期呼び出しを置き換える、すべてが期待通りに動作する場合:私のコントローラにさらにダウン

var getResults = function() { 
    var defer = $q.defer(); 
    $scope.data = [{"id":"1","email":"[email protected]",,"create_date":"2013-09-03T09:00:00.000Z"},{"id":"2","email":"[email protected]","create_date":"2013-09-03T11:10:00.000Z"}]; 
    _.each($scope.data[0], function(value, key) { 
    if (key !== 'id' && key !== 'email') { 
     $scope.columns.push({ 
     title: _str.capitalize(key), 
     field: key, 
     visible: true, 
     required: false 
     }); 
    } 
    }); 
    defer.resolve($scope.data); 
    return defer.promise; 
}; 

を私のinitコードが

getResults().then(function() { 
    $scope.tableParams.reload(); 
}); 

$scope.tableParams = new ngTableParams({... 
を呼び出します

約束が解決されるとすぐに、$scope.columnsが更新される前に$scope.tableParams.reload();が呼び出されると仮定します。

+1

としてコントローラに直接

var getResults = function() { var defer = $q.defer(); reportService.getReportResults({ report: $scope.id, version: $scope.version }).$promise.then(defer.resolve); return defer.promise; }; getResults().then(function(_data) { $scope.data = _data; _.each($scope.data, function(value, key) { if (key !== 'id' && key !== 'email') { $scope.columns.push({ title: _str.capitalize(key), field: key, visible: true, required: false }); } }); }); 

としてそれを試してみてくださいまたは 'そのgetResults()へ。その後、(...'コール'$ scope.tableParams'をインスタンス化したら? – Will

+1

こんにちは、私は角度に堪能ではありませんが、ここで$約束が何を意味するのか教えてください。 'version:$ scope.version })$ promise' これまでにこのようなことは何も見たことがありません。 –

+1

@Mridul https://docs.angularjs.org/api/ngResource/service/$resource、$ promiseを見つける –

答えて

2

ドキュメントのdemoに基づいて、それはかなり約束した例を作ることでした。 プロンプトから応答を得た後、新しいtableParamsおよびcolsオブジェクトを作成する必要があるようです。既存の列に行を追加するとウォッチャーがトリガーされないことがあります。

angular.module('app', ['ngTable']); 
 

 
angular.module('app').controller('Demo', function($scope, NgTableParams, dataService) { 
 
    $scope.cols = [{ 
 
    title: 'ID', 
 
    field: 'id', 
 
    visible: true 
 
    }, { 
 
    title: 'Email', 
 
    field: 'email', 
 
    visible: true 
 
    }, { 
 
    title: 'Create Date', 
 
    field: 'create_date', 
 
    visible: true 
 
    }]; 
 
    
 
    dataService 
 
    .getData() 
 
    .then(function (response) { 
 
     $scope.tableParams = new NgTableParams({}, { 
 
     dataset: response.results 
 
     }); 
 
     $scope.cols = $scope.cols.concat(response.cols); 
 
    }); 
 
}); 
 

 
angular.module('app').factory('dataService', function($timeout) { 
 
    return { 
 
    getData: function() { 
 
     return $timeout(function() { 
 
     var n = Math.round(Math.random() * 50) + 5; 
 
     var results = []; 
 

 
     for (var i = 0; i < n; i++) { 
 
      results.push({ 
 
      id: Math.random(), 
 
      email: 'ex' + Math.random() + '@example.com', 
 
      create_date: new Date(), 
 
      x: Math.round(Math.random() * 10), 
 
      y: Math.round(Math.random() * 25) 
 
      }); 
 
     } 
 

 
     return { 
 
      results: results, 
 
      cols: [ 
 
      { 
 
       title: 'X', 
 
       field: 'x', 
 
       visible: true 
 
      }, 
 
      { 
 
       title: 'Y', 
 
       field: 'y', 
 
       visible: true 
 
      } 
 
      ] 
 
     }; 
 
     }, 500); 
 
    } 
 
    }; 
 
});
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js"></script> 
 
<link rel="stylesheet" href="https://rawgit.com/esvit/ng-table/master/dist/ng-table.min.css"> 
 
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> 
 
<script src="https://rawgit.com/esvit/ng-table/master/dist/ng-table.min.js"></script> 
 

 
<div ng-app="app" ng-controller="Demo"> 
 
    <table ng-table-dynamic="tableParams with cols" class="table table-condensed table-bordered table-striped"> 
 
    <tr ng-repeat="row in $data"> 
 
     <td ng-repeat="col in $columns">{{row[col.field]}}</td> 
 
    </tr> 
 
    </table> 
 
</div>

1

理由は、あなたが(そして、約束のブロックを)非同期$スコープにデータを適用するということですので、あなたは角ダイジェストサイクルの外にある、とあなたのテーブルが更新されません。

$ scope.dataを同期して設定しているため、これはあなたのモックでは起こりません。 (A more detailed explanation can be found here

これを修正するには、$ scopeを使用してスコープを変更したことを通知する必要があります。

  • なし機能:$私は約束の

    • 悪い使い方を(いつでもあなたができる「延期」を避ける読む)に対処しようとするでしょう、あなたのコード、といくつかの他の問題を参照してください)(

      ダイジェストアプローチ

  • 一般の角に十分なおしゃべりの約束/について少し混乱、これは私があなたと同じ関数を記述したい方法です:

    var getResults = function() { 
    
        // fetch data 
        return reportService.getReportResults({ 
          report: $scope.id, 
          version: $scope.version 
         }) 
         .then(function(data) { 
    
          // assign the values 
          $scope.data = data.results 
    
          // notify angular to recheck his array 
          $scope.$digest() 
    
          // consider using a functional approach to have a cleaner code 
          _($scope.data) 
           .first() 
           .keys() 
           .filter(key => (key !== 'id' && key !== 'email')) 
           .each(key => { 
            $scope.columns.push({ 
             title: _str.capitalize(key), 
             field: key, 
             visible: true, 
             required: false 
            }) 
           }) 
           .value() 
    
          return $scope.data 
         }) 
    } 
    
    0

    あなたが移動した場合、ハードコードモックバージョンはどう

    reportService.getReportResults({ 
        report: $scope.id, 
        version: $scope.version 
        }).then(function(_data) { 
        $scope.data = _data; 
        _.each($scope.data, function(value, key) { 
          if (key !== 'id' && key !== 'email') { 
          $scope.columns.push({ 
           title: _str.capitalize(key), 
           field: key, 
           visible: true, 
           required: false 
          }); 
          } 
         }); 
    
        }); 
    
    関連する問題