angularjsasynchronousangular-ui-gridangular-promiseangular-ui-tabset

Uib-tab containing UI-GRID


I have a uib-tabset with four tabs:

<uib-tabset active="activeForm">
    <uib-tab index="0" heading="One"><ng-include src="'one.html'"></ng-include></uib-tab>
    <uib-tab index="1" heading="Two"><ng-include src="'two.html'"></ng-include></uib-tab>
    <uib-tab index="2" heading="Three"><ng-include src="'three.html'"></ng-include></uib-tab>
    <uib-tab index="3" heading="Four"><ng-include src="'four.html'"></ng-include></uib-tab>
</uib-tabset>

it has this controller:

$scope.tabs = [
  { title: 'One', route: 'one' },
  { title: 'Two', route: 'two' },
  { title: 'Three', route: 'three' },
  { title: 'Four', route: 'four' }
];

$scope.go = function(route) {
  $state.go(route);
};

Each tab has the same structure. They all contain a UI-GRID, and differ only in the data they contain:

$scope.dataList = [];
$scope.selectedFile = null;

$scope.gridOpts = {
enableFiltering: true,
enableRowSelection: true,
enableRowHeaderSelection: false,
multiSelect: false,
modifierKeysToMultiSelect: false,
noUnselect: false,
columnDefs: [..my fields..],
onRegisterApi: function(gridApi) {
  //set gridApi on scope
  $scope.gridApi = gridApi;
  gridApi.selection.on.rowSelectionChanged($scope,function(row){
    $scope.selectedFile = row.entity;
    // Switcher selezione/deselezione
    if ($scope.atLeastOneIsSelected === false){
      $scope.atLeastOneIsSelected = true;
    } else {
      $scope.atLeastOneIsSelected = false;
    }
  });

  gridApi.selection.on.rowSelectionChangedBatch($scope,function(rows){
    $scope.atLeastOneIsSelected = false;
  });

  $scope.getFirstData();
  }
};

$scope.addGridData = function(datalist) {
  $scope.dataList = $scope.dataList.concat(datalist);
  $scope.gridOpts.data = $scope.dataList;
};

$scope.getMoreDataAsync = function(firstData) {
  if ($scope.cancelPromise) {
    $scope.cancelPromise.resolve();
  }
  $scope.cancelPromise = $q.defer();
  TypeOneFileSrv.fileList.get(
    {
      userId: $scope.$stateParams.userId
    }, function(data) {
      if (data) {
        $scope.addGridData(data);
        blockUI.stop();
      }
    }, function(error) {
      if (error) {
        toaster.pop('error', 'Error', error);
      }
    }
  );
};

$scope.getFirstData = function() {
  blockUI.start('Loading 'ONE' tab...');
  $scope.selectedFile = null;
  $scope.dataList.length = 0;
  $scope.getMoreDataAsync(true);
};

At least, here is the Service which calls the server. As for the Controller, even the Services of the four tab are the same and differ only in the url:

angular.module('app').factory('TypeOneFileSrv', ['$resource', function($resource) {
var typeOne = {
  fileList: $resource('url_for_the_first_tab/:userId/?', {
    userId: '@userId'
  }, {
    get: {
      method: 'GET',
      isArray: true
    }
  })
};
return typeOne;
}]);

My problem is that, even if I added the blockUI in each tab, when I open the page containing the uib-tabset it seems sometimes it does not load all the data. Because for example I see the first two tabs that have the table populated, but the other two are not populated. Or the first two and the last, and so on.


Solution

  • Please try as shown below.

    app.js

    Inject ui.grid.autoResize module as shown below.

    var appModule = angular.module("app", [
        'ui.grid.autoResize'
    ]);
    

    Html

    Use ui-grid-auto-resize directive as shown below.

    <div class="grid" ui-grid="vm.yourGridOptions" ui-grid-auto-resize></div>
    

    css

    Give a width for your grid as shown below.

    .grid {
        width: 980px !important;
    }