Ng-table: Erreur : settings.$scope.$emit n'est pas une fonction

Créé le 29 avr. 2014  ·  50Commentaires  ·  Source: esvit/ng-table

Salut, je voulais juste commencer par dire à quel point j'apprécie le projet et le travail qui y est consacré.

Quoi qu'il en soit, j'ai l'impression d'avoir une erreur vraiment bizarre. Fondamentalement, je peux exécuter $scope.tableParams.reload() deux fois sans problème, mais à la troisième exécution, et à chacune des suivantes, j'obtiens l'erreur suivante :

TypeError: Cannot set property '$data' of null at [removed]/ng-table.js:411:55

Je crois que c'est tout le code pertinent, mais s'il manque quelque chose, faites le moi savoir :

$scope.lookupAddress = function(address){       
    var url = 'https://blockchain.info/multiaddr?cors=true&active='+address;
    $scope.loading = true;
    $scope.clearTableData();
    $http.get(url).success(function(data){
        $scope.loading = false;
        $scope.loaded = true;
        $scope.loadError = false;
        glob = data;

        //Removed code that processes the response. 

        };
        //Enables new data to be loaded, e.g. on a new address.
        //Pretty sure it's not working right now.
        if ($scope.tableParams){
            $scope.tableParams.reload();
        } 
        data = transactions; //this data var is what is called by the tables. Unsure if can remove.
        $scope.tableParams = new ngTableParams({
            page: 1,            
            count: 5,           // items per page
            sorting: {
                Date: 'desc' 
            }
        }, {
            total: transactions.length, 
            getData: function($defer, params) {
                data = transactions;
                var orderedData = params.sorting() ? $filter('orderBy')(data, params.orderBy()) : data;
                $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));

            }
        });
    }).
    error(function(data){
        $scope.loadError = true;
    });
}

$scope.clearTableData = function(){
    transactions = [];
    $scope.output = {}
    if ($scope.tableParams){
            $scope.tableParams.reload();
    } 
}
bug

Tous les 50 commentaires

J'ai fait un peu plus d'enquête.

Il semble que la rapidité du rappel pour le troisième soit instantanée, alors que pour les deux premiers il y a un délai.

En ajoutant console.log(data) à la ligne 406, j'ai remarqué le comportement suivant :
(modifier : je n'ai pas réalisé # liens vers des problèmes dans Github. Veuillez les ignorer.)

  1. Renvoie [] au chargement de la page (sans données dans le tableau)
  2. Après avoir appelé le $scope.lookupAddress() fn que j'ai écrit, il enregistre les données comme prévu peu de temps après l'appel (c'est-à-dire après le déclenchement des événements $http.get().success(), ce qui prend quelques instants).
  3. En l'appelant une deuxième fois, les étapes 1 et 2 se répètent dans l'ordre. #1 se déclenche immédiatement, et #2 avec le même délai.
  4. C'est là que l'erreur commence. D'abord les incendies #1, puis l'erreur détaillée dans le post précédent. Ce n'est qu'après que l'erreur a été déclenchée que #2 se déclenche alors.

Après #4 se produit, la table ne se recharge pas mais les données sont chargées correctement dans le backend. De plus, bien que je ne puisse pas appeler .reload() sans obtenir l'erreur, si je trie l'une des colonnes, les données de la table seront correctement mises à jour.

Wow, plus je creuse, plus cette erreur devient étrange.

Ajoutez ceci à ngTableParams : $scope: { $data: {} }

selon l'exemple 14 sur : http://bazalt-cms.com/ng-table/example/14

Merci d'avoir pris le temps d'aider.

J'ai regardé le code et j'ai fait comme tu m'as demandé. Le problème n'a pas disparu, mais l'erreur a changé. Maintenant, la troisième fois, il dit :

TypeError: undefined is not a function at [...]/ng-table.js:414:33

Pour être clair, c'est cette ligne:

settings.$scope.$emit('ngTableAfterReloadData');

Il semble donc que maintenant que $scope est défini sur undefined, l'appel de méthode ne fonctionne pas.

Y a-t-il une raison pour laquelle $scope.tableParams est défini dans le rappel $http.get().success(), et non dans le bloc fonction du contrôleur ?

La fonction $http.get().success() se trouve dans le bloc fonction du contrôleur. La raison pour laquelle $scope.tableParams est là, c'est parce qu'il a besoin d'accéder aux données renvoyées par $http.get().success().

Auriez-vous géré cela différemment ? Dois-je utiliser des promesses ? J'ai regardé à la fois l'exemple que vous avez lié et celui d'AJAX, mais je n'ai pas pu le reconstituer.

Cela ressemble à un problème de portée. Demandez à success() mettre success() .

$scope.transactions = [];

$scope.lookupAddress = function (address) {
  var url = 'https://blockchain.info/multiaddr?cors=true&active=' + address;
  $http.get(url).success(function (data) {
    $scope.transactions = data;
    $scope.tableParams.reload();
  });
};

$scope.tableParams = new ngTableParams({
  page: 1,            
  count: 5,
  sorting: {
      Date: 'desc' 
  }
}, {
  total: $scope.transactions.length, 
  getData: function($defer, params) {
    var data = $scope.transactions;
    var orderedData = params.sorting() ? $filter('orderBy')(data, params.orderBy()) : data;

    $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
  }
});

Merci encore de m'avoir aidé à traverser ça. J'ai travaillé sur ce problème toute la journée, et j'espère que je suis plus proche d'une solution.

Ainsi, comme pour d'autres threads que j'ai vus sur GitHub et StackOverflow concernant ngTables, j'ai remanié mon code pour utiliser des promesses au lieu d'un $http.get().success(). Voici donc à quoi cela ressemble maintenant :

$scope.transactions = [];
$scope.callBlockchain = function(address) {
    var url = 'https://blockchain.info/multiaddr?cors=true&active='+address;
    var promise = BlockchainService.lookupAddress(url);
    promise.then(function(data){
        $scope.transactions = data;
        $scope.tableParams.reload();
    })

$scope.tableParams = new ngTableParams({
    page: 1,            
    count: 5,           // items per page
    sorting: {
        Date: 'desc' 
    }
}, {
    total: $scope.transactions.length, 
    getData: function($defer, params) {
        var data = $scope.transactions;
        var orderedData = params.sorting() ? $filter('orderBy')(data, params.orderBy()) : data;
        $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));

    },
    $scope: { $data: {} }
})

Lorsque je lance ceci, j'obtiens une erreur, "undefined n'est pas une fonction", qui fait référence à la ligne 414 de ng-table.js . Plus précisément, il fait référence à la colonne 33, qui est correcte lorsque la méthode $emit est appelée.

Si je supprime $scope.tableParams.reload(), l'erreur disparaît, mais la table ne se met pas à jour. Écrire if ($scope.tableParams){$scope.tableParams.reload();} n'aide pas non plus à corriger le problème.

edit: Étant donné que l'erreur "undefined n'est pas une fonction" prend une demi-seconde pour apparaître après l'appel de la fonction, je suppose que l'erreur ne se déclenche qu'une fois la promesse résolue (c'est-à-dire que cela n'a pas à voir avec le fait d'essayer de résoudre prématurément les données de la promesse).

edit 2: Si je console.log() settings.$scope (l'objet qui appelle la méthode $emit() qui renvoie undefined), j'obtiens un comportement intéressant. Lors du premier chargement de la page, un objet est enregistré qui ressemble à un objet normal pour l'exécution du module. Cependant, après la résolution de la promesse dans callBlockchain() fn, un autre objet est enregistré qui contient les données que j'essaie de représenter sur les données.

Serait-ce le problème de portée dont vous avez parlé ? Il semble que les données de configuration de la table soient écrasées par les données de contenu.

J'avais exactement le même problème que vous jusqu'à ce que je trouve ça.

J'ai un modèle qui ressemble à ceci :

<div ng-controller="MyController">
  <!-- an HTML form here... -->
  <button ng-click="save()" >Save and Reload</button>
</div>
<div ng-controller="MyController">
  <table ng-table="tableParams">
  <!-- my table code here... -->
  </table>
</div>

À l'intérieur de MyController j'ai une fonction $scope.save qui enregistre un nouvel élément dans le service et déclenche un $scope.tableParams.reload() , ainsi que le classique $scope.tableParams = new ngTableParams(... . Après m'être cassé la tête pendant quelques heures avec ce problème et avoir lu le code de ngTable encore et encore, j'ai découvert que j'avais essentiellement un problème de $scope : 2 ngTableParams indépendants, un sans paramètres valides.$scope (celui sur mon contrôleur) et un autre un avec un settings.$scope valide (celui à l'intérieur du ngTableController). Lorsque ngTable appelle le rechargement après une pagination ou toute autre interaction, il utilise le bon (celui avec les paramètres valides. $ scope) MAIS lorsque j'essayais de recharger la table manuellement, je l'appelais de l'extérieur.

Après avoir compris comment fonctionne ngTable en interne, il était très simple de résoudre le problème en créant l'instance ngTableParams en tant que nouvelle usine et en l'injectant dans le contrôleur ; de cette façon, je suis sûr à 100% que l'instance ngTableParams est toujours la même que celle que j'ai l'intention d'utiliser.

En remarque, ce n'est PAS une bonne idée de définir $scope: {$data: {}} car ce n'est pas un objet $scope valide et aussi parce que chaque fois que les paramètres de la table changent (comme lors du passage à une page différente), le ngTableController le remplacer par son propre $scope, vous pouvez le voir ici

Après avoir compris comment fonctionne ngTable en interne, il était très simple de résoudre le problème en créant l'instance ngTableParams en tant que nouvelle usine et en l'injectant dans le contrôleur ; de cette façon, je suis sûr à 100% que l'instance ngTableParams est toujours la même que celle que j'ai l'intention d'utiliser.

@erickrdch Pourriez-vous peut-être élaborer à ce sujet avec du code.

Mon HTML :

<table class="table table-condensed table-hover" ng-table="tableParams">
<!--- table stuff --->
</table>

Dans mon contrôleur, je fais maintenant ceci:

if (batch.rules) {
      $scope.tableParams = new ngTableParams({
          page: 1,            // show first page
          count: 25,          // count per page
          sorting: {
            created: 'desc'     // initial sorting
          }
        },
        {
          total: batch.rules.length, // length of data
          getData: function ($defer, params) {

            // use build-in angular filter
            var filteredData = $filter('filter')(batch.rules, $scope.filter);
            var orderedData = params.sorting() ?
              $filter('orderBy')(filteredData, params.orderBy()) :
              filteredData;

            $scope.rules = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count());

            params.total(orderedData.length); // set total for recalc pagination
            $defer.resolve($scope.rules);
          }
        }
      );

$scope.$watch('filter.$', function () {
    $scope.tableParams.reload(); // TODO: Fix {scope: null} racecondition
});

Grâce à votre message, j'ai réalisé que $scope.tableParams.reload() est à l'origine de l'erreur. Mais comment le résoudre exactement.

Même problème. Surveillez un ensemble de données qui appelle $scope.tableParams.reload();

$scope.tableParams.reload() donne un Cannot set property '$data' of null la première fois que la montre s'exécute (il n'y a pas de données existantes dans les tableparams). Les appels suivants sont parfaits.

Je viens de trouver une solution de contournement moche mais efficace.
Enveloppez le $scope.watch dans un $timeout comme ceci :

$timeout( // Fix scope: null racecondition
  function(){
    $scope.$watch('filter.$', function () {
      $scope.tableParams.reload(); 
    });
  },
  0
);

Je crois que ce problème est causé par une condition de concurrence entre la promesse terminée dans la fonction getData() et l'appel de tableParams.reload() trop tôt, avant que la promesse ne se termine. J'ai changé mon code lors de l'appel de reload, et cela semble fonctionner correctement :

  if ($scope.tableParams.data.length > 0) {
    $scope.tableParams.reload();
  }

BTW, je n'ai pas utilisé $scope: { $data: {} } lors de la définition de ma table.

Merci pour la grande bibliothèque.

Existe-t-il encore une solution à ce problème ?

J'ai également eu le même problème et après 2 jours de lutte, j'ai réussi à le résoudre en utilisant la ligne de code suivante juste après le

$scope.tableParams = new ngTableParams(
{...},
{...}
);
 $scope.tableParams.settings().$scope = $scope;

Pour plus d'informations, veuillez vous référer à https://github.com/esvit/ng-table/blob/master/src/scripts/04-controller.js#L33

Avait le même problème.
La solution de Hasi a résolu le problème assez facilement.
Merci!

J'ai aussi trouvé la solution de Hasi pour fonctionner. Cependant, étant donné le nombre de personnes rencontrant cette erreur, une modification de ngTable lui-même pourrait-elle être afin de faire fonctionner les choses comme prévu? L'exemple 14 ne devrait tout simplement pas avoir besoin de la solution ngTableParams: $scope: { $data: {} } contournement

Tout d'abord un grand merci à l'équipe ngTable pour l'excellent travail :+1:
En ce qui concerne ce problème, la solution hasi'e a fonctionné pour moi aussi. Cependant, comme kbaltrinic l'a également mentionné, il serait bien d'avoir un correctif popper pour ce problème.

J'ai passé toute la journée à me casser la tête.. Merci erickrdch et hasi!

J'ai le même problème, mais je ne peux pas rassembler les fragments de solution de tout le monde pour fonctionner :(. J'en suis maintenant au stade où j'obtiens l'erreur ng-table.js:414 de $emit non définie. En particulier, c'est arrêter la production du code de sélection de page (je pense que quelque chose l'est). Quelqu'un a-t-il un exemple définitif d'une solution post-correction, par exemple un plunkr? Merci

Il n'y a rien de tel que de poster une question pour ensuite trouver la réponse quelques secondes plus tard. Cela fonctionne maintenant pour moi:

$scope.activityParams = new ngTableParams({
    page: 1,            // show first page
    count: 10           // count per page
}, {
    total: 0, // length of data
    counts: [],
    getData: function ($defer, params) {
        params.total($scope.activities.length);
        $defer.resolve($scope.activities.slice((params.page() - 1) * params.count(), params.page() * params.count()));
    },
});
$scope.activityParams.settings().$scope = $scope;

En particulier, la dernière ligne empêche $emit d'être indéfini (le problème de la ligne 414). Et le params.total($scope.activities.length) provoque la mise à jour correcte de la longueur lorsque mon serveur met à jour les valeurs $scope.activities

Je vais ajouter ma solution particulière. Pour toute autre personne dans le besoin / pour recueillir des suggestions pour l'améliorer.
Nécessaire pour recharger après avoir ajouté ou supprimé de la baie d'origine.

$scope.$watch('assets.length', function () {
  if ($scope.tableParams.settings().$scope) {
    $scope.tableParams.reload(); 
  }
});

Le $scope est défini dans le ngTableController , j'ai pensé que j'attendrais le leur. Cela n'a fait qu'une erreur pour moi lors du chargement initial, reload était appelé avant que le contrôleur ne soit peut-être initialisé?

J'ai lutté plusieurs heures sur la question. Enfin, voici un code qui fonctionne pour moi. Cela aidera peut-être quelqu'un :

'use strict'

angular.module 'aApp'
.controller 'ScenariosCtrl', ($scope, $modal, $filter, ngTableParams, Api) ->

  $scope.scenario = {}
  $scope.scenarios = []

  fetch = ->
    Api.getTestScenarios()

    .then (collection) ->
      $scope.scenarios = collection

      if $scope.tableParams?
        $scope.tableParams.total $scope.scenarios.length
        $scope.tableParams.reload()
      else
        pager = page: 1, count: 10
        items =
          total: $scope.scenarios.length
          getData: ($defer, params) ->
            data = $scope.scenarios
            orderedData = if params.sorting() then $filter('orderBy')(data, params.orderBy()) else data
            $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()))

        $scope.tableParams = new ngTableParams pager, items
        $scope.tableParams.settings().$scope = $scope

  $scope.newScenario = ->
    modal = $modal.open
      templateUrl: 'app/scenarios/modal-scenario.html'
      scope: $scope
      resolve:
        scenario: ->
          $scope.scenario

    modal.result
    .then ->
      Api.createTestScenario $scope.scenario
      .then (data) ->
        $scope.scenario = {}
        fetch()

    , ->
      $scope.scenario = {}

  fetch()

J'ai pu contourner ce problème en utilisant $timeout dans ma méthode $watch

  $scope.$watch("transactions", function (n, o) {
    $timeout(function(){ $scope.table.reload(); });
  });

Salut,

J'ai utilisé la solution de Hasi. Maintenant, je ne reçois aucune erreur pour cela.

settings.$scope.$emit('ngTableAfterReloadData');

mais maintenant je suis confronté à un autre problème. D'une manière ou d'une autre, le panneau de pagination ne se met pas à jour.
Dans mon cas, les données sont chargées dynamiquement. Pour le premier chargement de données, il calcule les pages correctes et affiche le panneau de pagination. Mais après cela, le panneau de pagination ne change pas bien que les données changent.

Lorsque j'ai débogué le code, j'ai découvert que le code suivant n'était pas appelé.

scope.params.settings().$scope.$on('ngTableAfterReloadData', function () {
                    scope.pages = scope.params.generatePagesArray(scope.params.page(), scope.params.total(), scope.params.count());
                }, true);

Est-ce que quelqu'un a des indices ? Merci d'avance.

salut, j'ai le même problème. J'ai utilisé la solution de Hasi. Maintenant, je ne reçois aucune erreur pour cela.
mais les données de la table ne sont pas mises à jour. car ce bloc de code ne s'exécute pas.

 scope.params.settings().$scope.$on('ngTableAfterReloadData', function () {
 scope.pages = scope.params.generatePagesArray(scope.params.page(), scope.params.total(), scope.params.count());
 }, vrai);

y a-t-il une idée sur ce problème compliqué?

Bouger ce fil pour faire savoir à tous que la solution de contournement de @hasi est la seule qui a fonctionné pour moi.

J'ai essayé toutes les solutions suggérées ici, mais aucune d'entre elles ne m'a aidé à résoudre mon problème.
Toute contribution à ce sujet est grandement appréciée.
Pour le problème s'il vous plaît visitez le lien:
http://stackoverflow.com/questions/28081205/ngtable-not-loading-data

Quelqu'un, des suggestions ou quoi que ce soit sur cette question? Est-ce que quelqu'un suit ce fil?

Cela n'aidera pas directement, mais ma solution était d'abandonner angulaire (en particulier compte tenu de la feuille de route annoncée récemment) et d'utiliser le knockout. Je dois dire que cela a été beaucoup moins douloureux.

Je n'ai pas la possibilité d'abandonner Angular. Cela doit être fait en utilisant AngularJS uniquement. J'ai essayé de nombreux messages et suggestions, mais aucun ne semble fonctionner.

@ nick250386 - étant donné que les causes du problème peuvent différer, vous auriez peut-être plus de chance de dupliquer votre problème dans jsfiddle afin que nous puissions l'examiner.

Je suis d'accord que laisser tomber complètement angulaire sur un module de table est peu susceptible d'être une solution pour beaucoup; les applications peuvent être assez élaborées et en voie d'achèvement.

Moi aussi j'ai essayé tous les hacks possibles et aucun ne fonctionne.
Parfois (1 sur 8) la table est mise à jour correctement lors de l'appel de reload(), les 7 autres fois je reçois :

TypeError : undefined n'est pas une fonction sur :
settings.$scope.$emit('ngTableAfterReloadData');

J'utilise actuellement la v0.4.3, une suggestion sur la façon de recharger la table lors d'un changement de données ?

J'ai le même problème, aucun des hacks essayés ici ne fonctionne.
Seuls certains rechargements fonctionnent correctement.

Le tableau n'est pas du tout utilisable.

Avez-vous essayé d'exécuter dans Chrome, à l'intérieur des outils de développement, avec « arrêter sur les exceptions non gérées » activé et en vérifiant exactement où se trouve l'appel de fonction tenté ? Ce n'est peut-être pas là où vous pensez que c'est...

Merci @OracPrime voici le résultat de l'exception :

: TypeError : undefined n'est pas une fonction
message : "undefined n'est pas une fonction"
stack : "TypeError : undefined n'est pas une fonction
sur http://localhost :8000/js/libs/angular/ng-table.min.js:455:33
à l.promise.then.J (http://localhost:8000/js/libs/angular/angular-1.2.28.min.js:101:96)
sur http://localhost :8000/js/libs/angular/angular-1.2.28.min.js:102:259
à h.$get.h.$eval (http://localhost:8000/js/libs/angular/angular-1.2.28.min.js:113:32)
à h.$get.h.$digest (http://localhost:8000/js/libs/angular/angular-1.2.28.min.js:110:117)
à h.$get.h.$apply (http://localhost:8000/js/libs/angular/angular-1.2.28.min.js:113:362)
à HTMLDivElement.(http://localhost:8000/js/libs/angular/angular-1.2.28.min.js:195:229)
sur HTMLDivElement.x.event.dispatch (http://localhost:8000/js/libs/jquery-2.0.2.min.js:4:9843)
sur HTMLDivElement.x.event.add.y.handle (http://localhost:8000/js/libs/jquery-2.0.2.min.js:4:6633)"

La ligne 455 est :

settings.$scope.$emit('ngTableAfterReloadData');

Le problème est le suivant : je ne parviens pas à actualiser la table lorsque les données changent, j'ai le même problème que @Evilcry , parfois cela fonctionne (la plupart) d'autres fois, cela ne fonctionne pas. C'est mon code :

$scope.tableParams = new ngTableParams({
                        page: 1,
                        count: 25,
                        filter: { },
                        sorting: { "date": "desc" } }, {
                        filterDelay: 200,
                        counts: [],
                        total: data.length,
                        getData: function($defer, params) {
                            $defer.resolve(data.slice((params.page() - 1) * params.count(), params.page() * params.count()));
                        },
                        $scope: { $data: {} }
                    });

Lorsque les données changent, j'émets simplement un :

$scope.tableParams.reload();

Éditer
Hors des contraintes de temps sur mon projet actuel, je viens de passer à trNgGrid : http://moonstorm.github.io/trNgGrid/release/index.html J'ai pu convertir l'ensemble du projet en moins d'une heure et cela fonctionne à merveille jusqu'à présent.

Quelqu'un a-t-il eu l'occasion d'examiner cela? J'ai vérifié tellement de résultats sur Google à ce sujet, et à de nombreux endroits, les gens sont confrontés au même problème. Dans un scénario, il y avait 3 tables à charger, ce que j'ai pu faire sans aucun problème. Dans mon cas problématique, la première table se charge sans aucun problème. Sur la base des données présentes dans la première ligne du tableau, les données doivent être chargées dans le deuxième tableau. Je peux obtenir les nouvelles données pour la deuxième table, mais ces données ne sont pas rendues. J'ai essayé toutes les solutions présentes sur Internet, mais aucune ne semble fonctionner. Pour référence, vous pouvez vous référer aux détails de mon cas présent à:

http://stackoverflow.com/questions/28081205/ngtable-not-loading-data

Toutes les idées sont les bienvenues sur ce sujet.

Chaque fois que j'essaie de recharger la table (à l'intérieur d'un observateur) après avoir obtenu les données requises, j'obtiens l'erreur :
TypeError : impossible de définir la propriété '$data' de null
J'ai approfondi la question. Voilà ce que j'ai trouvé :
Avant, lorsqu'il n'y a pas de données pour la table :

{"data":[],"$params":{"page":1,"count":10,"filter":{"location":"","country":"","region":""},"sorting":{"location":"asc"},"group":{},"groupBy":null},"filterBuffer":{}}

Après l'exécution de la montre, la variable concernée est chargée avec des données (ceci est confirmé), mais les paramètres de la table restent inchangés :

{"data":[],"$params":{"page":1,"count":10,"filter":{"location":"","country":"","region":""},"sorting":{"location":"asc"},"group":{},"groupBy":null},"filterBuffer":{}}

Toutes les idées pourquoi cela se produit

J'ai mis à jour mon code en fonction des modifications que j'ai apportées à mon commentaire précédent avec les journaux de la console. N'hésitez pas à poser des questions.
http://stackoverflow.com/questions/28081205/ngtable-not-loading-data

OK..J'ai réussi à ce que cela fonctionne avec une combinaison des solutions ci-dessus et une autre chose. J'ai utilisé à la fois le correctif hasi de

$scope.tableParams.settings().$scope = $scope; pour se débarrasser de l'erreur

et de josey :

$scope.$watch("mygriddatavar", fonction (n, o) {
$timeout(function(){ $scope.tableParams.reload(); });
});

CEPENDANT, j'ai dû utiliser deux contrôleurs séparés. Mon application effectue une recherche et je liste les résultats dans le tableau. Cet appel $http a été effectué dans un contrôleur, les résultats ont été renvoyés et la réponse JSON a été stockée dans $scope.mygriddatavar. J'ai créé mes tableParams dans un contrôleur séparé et ajouté la montre d'en haut également dans ce contrôleur. Je ne sais pas pourquoi cela fonctionne, mais j'ai tout essayé dans le même contrôleur et cela n'a jamais fonctionné. Ce n'est qu'après avoir créé un contrôleur séparé pour la table que cela a fonctionné. Cela ressemble donc à quelque chose comme :

.controller('mainController',['$scope','$route', '$animate', '$http'','ngTableParams', function($scope,$route, $animate,$http,ngTableParams) {
...blah...blah...
  $scope.searchFunc = function(){
                         var getsearchres = {
                                        url: mysearchapi,
                                        method: 'post',
                                        data : somedata

                            };
                            $http(getsearchres )
                                      .success(function(data, status, headers, config) {

                                            $scope.mygriddatavar= data;


                                  })
                                  .error(function(data, status, headers, config) {

                                           $scope.alert = 'There was a network error. Try again later.';

                                    })
}
}])
.controller('searchControl', function($scope,$http, $filter, $timeout, ngTableParams) {

$scope.$watch('mygriddatavar', function(n,o){
                    if($scope.tableParams){
                      $timeout(function(){ $scope.tableParams.reload(); });
                     }
                }
             );

    $scope.tableParams = new ngTableParams({
        page: 1,            // show first page
        count: 10,          // count per page
        filter: {
            //Internal_ID: ''       // initial filter
        },
        sorting: {
            Internal_ID: 'asc'     // initial sorting
        }
    }, {
        total: $scope.mygriddatavar.length, // length of data
        getData: function($defer, params) {
            data = $scope.mygriddatavar;
            //use build-in angular filter
            var filteredData = params.filter() ?
                    $filter('filter')(data, params.filter()) :
                    data;
            var orderedData = params.sorting() ?
                    $filter('orderBy')(filteredData, params.orderBy()) :
                    filteredData;

            params.total(orderedData.length); // set total for recalc pagination
            $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
        },
        $scope: { $data: {} }
    });

    $scope.tableParams.settings().$scope = $scope;
})

Je pense vraiment que ces difficultés pourraient être plus facilement résolues avec PROPER
DOCUMENTATION API plutôt que d'avoir à passer au crible des exemples de code aléatoires et
espérer le meilleur ...

_Josey Téléphone : 918.926.6678 | Gtalk: [email protected] [email protected]
Twitter : @joseym http://www.twitter.com/joseym LinkedIn : Josey Morton
http://www.linkedin.com/profile/view?id=59813483 Github : joseym
http://www.github.com/joseym Blog : Tumblr http://tumblr.joseymorton.com_

Le jeudi 29 janvier 2015 à 9h45, cscrum [email protected] a écrit :

OK..Je l'ai fait fonctionner avec une combinaison des solutions ci-dessus plus une
plus de chose. J'ai utilisé à la fois le correctif hasi de

$scope.tableParams.settings().$scope = $scope; pour se débarrasser de l'erreur

et de josey :

$scope.$watch("mygriddatavar", fonction (n, o) {
$timeout(function(){ $scope.tableParams.reload(); });
});

CEPENDANT, j'ai dû utiliser deux contrôleurs séparés. Mon application effectue un
recherche et je liste les résultats dans le tableau. Cet appel $http a été fait dans un
contrôleur, les résultats renvoyés et la réponse JSON ont été stockés dans
$scope.mygriddatavar. J'ai créé mon tableParams dans un contrôleur séparé et
ajouté la montre d'en haut également dans ce contrôleur. Je ne sais pas pourquoi cela
fonctionne, mais j'ai tout essayé dans le même contrôleur et cela n'a jamais fonctionné. C'était
seulement après avoir créé un contrôleur séparé pour la table que cela a fonctionné. Alors
ça ressemble à quelque chose comme :

.controller('mainController',['$scope','$route', '$animate',
'$http'','ngTableParams', function($scope,$route,
$anime,$http,ngTableParams) {
... bla... bla...
$scope.searchFunc = function(){
var getsearchres = {
URL : mysearchapi,
méthode : 'post',
données : quelques données

                    };
                    $http(getsearchres )
                              .success(function(data, status, headers, config) {

                                    $scope.mygriddatavar= data;


                          })
                          .error(function(data, status, headers, config) {

                                   $scope.alert = 'There was a network error. Try again later.';

                            })

}
}])
.controller('searchControl', function($scope,$http, $filter, $timeout,
ngTableParams) {

$scope.$watch('mygriddatavar', function(n,o){
if($scope.tableParams){
$timeout(function(){ $scope.tableParams.reload(); });
}
}
);

$scope.tableParams = new ngTableParams({
page : 1, // afficher la première page
compte : 10, // compte par page
filtre : {
//Internal_ID : '' // filtre initial
},
tri : {
Internal_ID : 'asc' // tri initial
}
}, {
total : $scope.mygriddatavar.length, // longueur des données
getData : function($defer, paramètres) {
données = $scope.mygriddatavar ;
// utiliser le filtre angulaire intégré
var filteredData = params.filter() ?
$filter('filter')(données, params.filter()) :
Les données;
varDonnéesOrdonnées = params.sorting() ?
$filter('orderBy')(filteredData, params.orderBy()) :
données filtrées ;

    params.total(orderedData.length); // set total for recalc pagination
    $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
},
$scope: { $data: {} }

});

$scope.tableParams.settings().$scope = $scope;

})

-
Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/esvit/ng-table/issues/297#issuecomment-72046727 .

:+1: pour une correction de bug

@joseym pensez -vous que nous pouvons utiliser ce code comme base pour documenter la solution de contournement jusqu'à ce qu'une correction de bogue soit en place ? https://github.com/esvit/ng-table/blob/master/src/scripts/04-controller.js#L23 -L30 (L30 est, à mon avis, la solution de contournement actuelle)

est-ce vraiment closed ? :-P

Je suis plus qu'heureux de documenter la solution de contournement en tant que "solution" provisoire, comme mentionné dans mon dernier commentaire, mais même dans ce cas, le problème devrait toujours rester ouvert.

Pourquoi fermer tous ces problèmes ouverts et non résolus ?

donner une description précise en mentionnant la version angulaire, la version ng-table.

donner un moyen de reproduire votre problème, le mieux serait avec un exemple en cours, vous pouvez utiliser plunkr. Notez que si vous souhaitez imiter le comportement de chargement ajax, vous pouvez utiliser le service angulaire $timeout ou $httpBackend.

@iyel, je peux m'en occuper le week-end quand j'ai un peu de temps. Je pense que 2 plunkers seraient les meilleurs: 1 pour montrer l'erreur (ainsi l'isoler formellement [0]) et 1 pour montrer la solution de contournement actuelle. J'enverrai ensuite un petit PR pour le README[1] pour avoir une zone "Problèmes connus", en référence aux plunkers et à un certain contexte.

[0] cela permettra de fermer ce problème et d'ouvrir un problème plus spécifique qui peut se concentrer sur l'adressage de la résolution du problème spécifique.

[1] Merci d'avoir mis à jour le fichier readme avec les directives de contrib... à peu près essentiel pour les projets plus importants !

Tous,

J'essaie de reproduire le problème dans ce Plunker :
http://plnkr.co/edit/q8DJJF?p=preview (essayez de saisir les identifiants utilisateur 1, 2, 3, etc.)

Cependant, je ne vois plus l'erreur. J'ai essayé avec :

  • Angulaire 1.3 + ngTable 0.3.0
  • Angulaire 1.2 + ngTable 0.3.0
  • Angulaire 1.3 + ngTable 0.5.0
  • Angulaire 1.2 + ngTable 0.5.0

La solution de @hasi fonctionnait depuis

J'ai essayé de garder le Plunker aussi proche que possible du contrôleur de @acoard (sur la base de ses quelques itérations, c'est-à-dire).

Puis-je obtenir de l'aide pour reproduire le problème dans ce Plunker ?

Salut tout le monde,
Je viens de rencontrer ce problème sur un projet dont j'ai hérité. Quelqu'un a mis à jour la dernière version angulaire (1.4.*) et nous avions des problèmes avec ngTable, alors je l'ai mis à jour vers la version 1.0.0 bêta et j'ai vu l'erreur.

Il semble que la portée soit «malformée» dans le ngTable. J'ai essayé un tas de correctifs mentionnés ci-dessus à part

$scope.tableparams.settings().$scope = $scope

Ce qui a fonctionné pour moi, c'est de configurer le $scope pour les paramètres de table lors de la création (je n'ai jamais utilisé ce plugin auparavant, donc je ne connais pas le fonctionnement interne du plugin ou comment il doit être correctement utilisé)

Notre code ressemble donc à ceci (ceci a été tiré du post de l'utilisateur


$scope.tableParams = new ngTableParams({
    page: 1,            
    count: 5,           // items per page
    sorting: {
        Date: 'desc' 
    }
}, {
    total: $scope.transactions.length, 
    getData: function($defer, params) {
        var data = $scope.transactions;
        var orderedData = params.sorting() ? $filter('orderBy')(data, params.orderBy()) : data;
        $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));

    },
    $scope: { $data: {} }
})

Dans notre code, il suffit de remplacer
$scope: { $data: {} }

Avec
$scope: $scope
OU ALORS
$scope: $scope.new()

Correction du problème.

Donc, dans mon cas, les lignes ressemblent plus à

$scope.$data = {};
...
$scope.tableParams = new ngTableParams({
    page: 1,            
    count: 5,           // items per page
    sorting: {
        Date: 'desc' 
    }
}, {
    total: $scope.transactions.length, 
    getData: function($defer, params) {
        var data = $scope.transactions;
        var orderedData = params.sorting() ? $filter('orderBy')(data, params.orderBy()) : data;
        $defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));

    },
    $scope: $scope
})

J'ai donc ajouté le $data à la portée locale car je ne pense pas que nous ayons besoin d'une portée isolée ou d'une portée enfant et tout fonctionne.

J'espère que cela t'aides. S'il vous plaît laissez-moi savoir si c'est un non-non absolu.

à votre santé
kle

Une simple modification et tout fonctionne très bien -
var x = function(){}; if( (typeof newParams.reload) == (typeof x)) newParams.reload();
Comme je l'ai vérifié avec console.log(), si vous avez plusieurs contrôleurs, cela provoque un problème lorsque Ng-Table essaie de recharger l'objet avant son objet NgTableParams. Après cette modification, le code fonctionne sans erreur.

La plupart des suggestions ci-dessus contournent l'erreur et ne traitent pas le vrai problème.

Je rencontre ce problème exactement à la 3ème fois. Les données sont en réponse et l'erreur l'a empêchée de se lier.

Pour reproduire ce problème, créez simplement une recherche simple et utilisez ng-Table pour afficher les résultats. Je vous rencontrerai certainement cette erreur après votre 3ème recherche. Si ce n'est pas le cas, merci de partager votre méthode. Merci.

Cette page vous a été utile?
0 / 5 - 0 notes