2016-09-14 2 views
0

J'utilise ngtable (1.0.0) pour afficher les enregistrements récupérés du côté serveur. Mon contrôleur js ressemble à ceci:Comment éviter le chargement de données à partir du serveur à chaque fois que je fais un tri/pagination avec ngtable

ristoreApp.controller("fmCtrl", 
    ['$scope', '$filter', 'fmFactory', 'NgTableParams', function($scope, $filter, fmFactory, NgTableParams) { 
     var self = this; 
     $scope.selection = '0'; 
     $scope.fmSearch = function() { 
      if ($scope.selection == '0') { 
       self.tableParams = new NgTableParams({ 
        page: 1,   // show first page 
        count: 10,   // count per page 
        sorting: { 
         frReportId: 'asc' 
        } 
       }, { 
        getData: function (params) { 
         return fmFactory.getAll() 
          .then(function(response) { 
           var reports = response.data; 
           params.total(reports.length); 
           console.log(params.total()); 
           var sorted = params.sorting() ? $filter('orderBy')(reports, params.orderBy()) : reports; 
           return sorted.slice((params.page() - 1) * params.count(), params.page() * params.count()); 
         }); 
        } 
       }); 
      } 
     } 
    }] 
) 

HTML pour la table:

<div ng-controller="fmCtrl as fm"> 
    <div class="container"> 
     <div class="row top-margin-80"> 
      <div class="col-md-12"> 
       <div class="input-group" id="adv-search"> 
        <input type="text" class="form-control" ng-model="keyword" placeholder="Enter MRN or report ID" /> 
        <div class="input-group-btn"> 
         <div class="btn-group" role="group"> 
          <div class="dropdown dropdown-lg"> 
           <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"><span class="caret"></span></button> 
           <div class="dropdown-menu dropdown-menu-right" role="menu"> 
            <form class="form-horizontal" role="form"> 
             <div class="form-group"> 
              <label for="filter">Search by</label> 
              <select class="form-control" ng-model="selection"> 
               <option value="0" selected>All Reports</option> 
               <option value="1" >MRN</option> 
               <option value="2">ReportID</option> 

              </select> 
             </div> 
             <div class="form-group"> 
              <input class="form-control" type="text" ng-model="optionword" ng-hide="selection == '0'"/> 
             </div> 
            </form> 
           </div> 
          </div> 
          <button type="button" class="btn btn-primary" ng-click="fmSearch()"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></button> 
         </div> 
        </div> 
       </div> 
      </div> 
     </div> 
    </div> 

    <div class="container"> 
     <table ng-table="fm.tableParams" class="table table-bordered table-striped table-condensed" show-filter="false"> 
      <tr ng-repeat="report in $data"> 
       <td data-title="'ReportId'" filter="{frReportId: 'text'}" sortable="'frReportId'" class="text-center"> 
        {{report.frReportId}}</td> 
       <td data-title="'BlockId'" filter="{frBlockId: 'text'}" sortable="'frBlockId'" class="text-center"> 
        {{report.frBlockId}}</td> 
       <td data-title="'MRN'" filter="{mrn: 'text'}" sortable="'mrn'" class="text-center"> 
        {{report.mrn}}</td> 
       <td data-title="'Name'" filter="{frFullName: 'text'}" sortable="'frFullName'" class="text-center"> 
        {{report.frFullName}}</td> 
       <td data-title="'Diagnosis'" filter="{frDiagnosis: 'text'}" sortable="'frDiagnosis'" class="text-center"> 
        {{report.frDiagnosis}}</td> 
       <td data-title="'File'" class="text-center"><a ng-href="{{report.filepath}}">{{report.frReportId}}.xml</a> 
        </td> 

      </tr> 
     </table> 
    </div> 
</div> 

Il fonctionne bien en quelque sorte. Le problème est quand je clique sur les titres pour trier et bouton de page pour aller à la page suivante, il fait un appel ajax au serveur pour récupérer des données encore. J'ai plus de 2000 enregistrements dans la base de données, chaque fois que je fais quelque chose à la table, il faut 5 secondes pour répondre ce qui est très ennuyeux. Comment est-ce que je fais charger les données seulement la première fois et le cache sur le côté client pour la manipulation future?

+0

Où est votre code HTML? Il semble que vous appelez getData chaque fois que vous cliquez. Vous avez seulement besoin d'obtenir les données une fois et de les enregistrer dans la portée. Vous pouvez utiliser le chargement paresseux pour la pagination. Vous ne pouvez pas vraiment aider sans voir tout votre code. –

+1

Essayez de mettre votre response.data dans une variable $ scope $ scope.reports = response.data, puis faites-y référence pour la pagination et le tri, de toute façon je ne pense pas que de mal à 2000 dossiers au client est une bonne idée ... – Vermicello

+1

stockez les données dans un service ou mettez en cache la requête $ http conformément aux documents. Soyez prudent cependant avec votre stratégie si les données sont susceptibles d'être modifiées par d'autres utilisateurs – charlietfl

Répondre

0

Finalement, je l'ai mis au travail. La solution consiste à déplacer l'appel ajax var Ajax = fmFactory.getAll(); à l'extérieur du constructeur ngtable.

   var Ajax = fmFactory.getAll(); 
       self.tableParams = new NgTableParams({ 
        page: 1,   // show first page 
        count: 10,   // count per page 
        sorting: { 
         frReportId: 'asc' 
        } 
       }, { 
        getData: function (params) { 
         return Ajax.then(function(response) { 
           var reports = response.data; 
           params.total(reports.length); 
           console.log(params.total()); 
           var sorted = params.sorting() ? $filter('orderBy')(reports, params.orderBy()) : reports; 
           return sorted.slice((params.page() - 1) * params.count(), params.page() * params.count()); 
         }); 
        } 
       });