2017-04-21 1 views
0

Je suis un programmeur C# et MVC expérimenté, mais je commence tout juste avec AngularJS. J'utilise ngTable (en essayant de toute façon) avec un succès limité, mais un problème que je ne peux pas résoudre - peu importe ce que je fais, je n'arrive pas à actualiser une table particulière lorsque les données ont changé.ngTable ne recharge pas les données

Je reçois des données d'une API Web via une usine - c'est une liste de fournisseurs associés à un produit particulier. La première fois que l'écran est chargé, les données sont ramenées et la table s'affiche correctement - tout appel ultérieur, les données sont renvoyées, mais la table n'est pas mise à jour. Les autres zones de la page sont mises à jour comme prévu.

J'ai effectué une journalisation de la console et je peux voir que les données reviennent. J'ai essayé la fonction tableParams.reload(), et en réglant le tableParams.total() mais rien ne semble déclencher la table à actualiser.

C'est ma fonction dans le contrôleur:

function getStockSupplier() { 
     console.log("getStockSupplier()"); 
     $scope.stockSupplierTableParams = {}; 

     stockSupplier.getAll({ url: "localhost:52457", sku: $scope.model.sku }) 
      .$promise.then(function (response) { 
       $scope.stockSupplier = response; 

       $scope.stockSupplierTableParams = new NgTableParams({ 
       }, { 
        dataset: response 
       }); 

       console.log("Got result"); 
       console.log("Length: " + $scope.stockSupplierTableParams.settings().dataset.length); 

       $scope.stockSupplierTableParams.reload(); 

      }, function (response) { 
       alert('no stock item'); 
       $scope.stockSupplier = null; 
      }); 
    } 

Et voici mon code HTML:

<div ng-controller="stockController"> 
     <div> 
      <table ng-table="stockSupplierTableParams" class="table table-condensed table-bordered table-striped"> 
       <tr ng-repeat="issue in $data"> 
        <td data-title="'Supplier1'"> 
         {{issue.SupplierName}} 
        </td> 
        <td data-title="'On Order'"> 
         {{issue.OnOrder}} 
        </td> 
       </tr> 

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

Je suis à une perte complète - il peut être quelque chose de fondamental qui me manque , mais ça me rend fou, donc toute aide est appréciée.

EDIT: Voici le code de l'appel du service API Web, au cas où cela aurait un intérêt. En outre, je dois souligner que le HTML ci-dessus est utilisé dans une directive, si cela fait une différence.

var myService = angular.module('myService', ['ngResource']); 
myService.factory('stockSupplier', [ 
    '$resource', 
    function ($resource) { 
     return $resource('http://:url/api/StockInfo?Sku=:sku&StockSupplier=true', 
      { 
       url: '@url', 
       sku: '@sku' 
      }, 
      { 
       getAll: { 
        method: 'GET', 
        isArray: true 
       }, 
      }); 
    } 
]); 

Répondre

0

Je l'ai eu le travail! Bien que je ne sois pas sûr à 100% comment, si des développeurs Angular expérimentés pouvaient l'expliquer, je serais reconnaissant. Il y a deux parties à cela.

Fondamentalement - au lieu de définir l'ensemble de données à l'objet de réponse de l'appel API, je l'ai défini à la variable $scope.stockSuppler. Puis, je explicitement vide cette variable avant la mise à jour - le code ci-dessous:

function getStockSupplier() { 
     console.log("getStockSupplier()"); 
     $scope.tableIsReady = false; 
     $scope.stockSupplierTableParams = {}; 
     $scope.stockSupplier = []; 

     stockSupplier.getAll({ url: "localhost:52457", sku: $scope.model.sku }) 
      .$promise.then(function (response) { 
       $scope.stockSupplier = response; 

       $scope.stockSupplierTableParams = new NgTableParams({ 
       }, { 
        dataset: $scope.stockSupplier 
       }); 

       console.log("Got result"); 
       console.log("Length: " + $scope.stockSupplierTableParams.settings().dataset.length); 
       $scope.stockSupplierTableParams.reload(); 
       $scope.tableIsReady = true; 
      }, function (response) { 
       alert('no stock item'); 
       $scope.stockSupplier = null; 
      }); 
    } 

Aussi, je retire le ngController="stockController" du code HTML directive - la directive est appelée dans une div qui a déjà défini le contrôleur. Avoir le contrôleur défini deux fois semble l'avoir confondu aussi. Je devrais souligner que seulement faire ces deux changements, je dois travailler. L'un ou l'autre seulement, cela ne fonctionne toujours pas correctement.

La table est maintenant mise à jour comme prévu avec les autres parties de la page. Je ne suis pas sûr pourquoi l'utilisation de la variable de portée plutôt que la réponse de l'API fait une différence, mais cela a fait l'affaire.

0

J'ai une solution simple, vous pouvez déposer réengendrer lorsque les données chargées:

HTML

<div ng-controller="stockController"> 
    <div data-ng-if="tableIsReady"> 
     <table ng-table="stockSupplierTableParams" class="table table-condensed table-bordered table-striped"> 
      <tr ng-repeat="issue in $data"> 
       <td data-title="'Supplier1'"> 
        {{issue.SupplierName}} 
       </td> 
       <td data-title="'On Order'"> 
        {{issue.OnOrder}} 
       </td> 
      </tr> 

     </table> 
    </div> 
    <div data-ng-if="!tableIsReady"> 
     // you can put loader here 
    </div> 
</div> 

JS

function getStockSupplier() { 
    console.log("getStockSupplier()"); 
    $scope.stockSupplierTableParams = {}; 

    $scope.tableIsReady = false; // here we hide table, and show loader 

    stockSupplier.getAll({ url: "localhost:52457", sku: $scope.model.sku }) 
     .$promise.then(function (response) { 
      $scope.stockSupplier = response; 

      $scope.stockSupplierTableParams = new NgTableParams({ 
      }, { 
       dataset: response 
      }); 

      console.log("Got result"); 
      console.log("Length: " + $scope.stockSupplierTableParams.settings().dataset.length); 

      $scope.stockSupplierTableParams.reload(); 

      $scope.tableIsReady = true; // here we show table again 

      $scope.$apply() // start digest 

     }, function (response) { 
      alert('no stock item'); 
      $scope.stockSupplier = null; 
     }); 
} 

Sinon, votre code est bien, vous pouvez juste oublier mettre $scope.$apply() après $scope.stockSupplierTableParams.reload();

+0

Salut - merci pour la réponse!J'ai essayé ce que tu as suggéré mais ça ne fait aucune différence. J'ai essayé de faire ng-si moi-même avant, pensant que cela pourrait forcer un redessin, mais j'ai mis le ng-if et $ scope. $ Apply() selon votre exemple et cela ne fait aucune différence - la table ne se met toujours pas à jour . En fait, je reçois maintenant une erreur dans la console de l'instruction $ apply() en disant '$ digest déjà en cours'. Appréciez cependant la suggestion, –

+0

Qu'est-ce que '$ promise'? Pourquoi ne pas simplement ".then". Je pense que le problème est – Leguest

+0

$ promesse est utilisé parce que c'est un appel asynchrone à l'API Web - si je le supprime, je reçois juste une erreur dans la console en disant que '.then() n'est pas une fonction'. Je vais ajouter dans mon code de service à la question originale pour plus de clarté. –