Question Combattre le contrôleur exécutant AngularJS deux fois


Je comprends AngularJS traverse deux fois le code, parfois même plus, comme $watch événements, vérifiant constamment les états du modèle, etc.

Cependant mon code:

function MyController($scope, User, local) {

var $scope.User = local.get(); // Get locally save user data

User.get({ id: $scope.User._id.$oid }, function(user) {
  $scope.User = new User(user);
  local.save($scope.User);
});

//...

Est exécuté deux fois, en insérant 2 enregistrements dans ma base de données. Je suis clairement en train d'apprendre alors que je me bats la tête contre ça depuis des lustres!


514
2018-03-20 21:43


origine


Réponses:


Le routeur de l'application a spécifié la navigation vers MyController ainsi:

$routeProvider.when('/',
                   { templateUrl: 'pages/home.html',
                     controller: MyController });

Mais je l'avais aussi dans home.html:

<div data-ng-controller="MyController">

Cela a digéré le contrôleur deux fois. Enlever le data-ng-controller attribut du HTML a résolu le problème. Alternativement, le controller: La propriété a pu être supprimée de la directive de routage.

Ce problème apparaît également lors de l'utilisation de la navigation par onglets. Par exemple, app.js pourrait contenir:

  .state('tab.reports', {
    url: '/reports',
    views: {
      'tab-reports': {
        templateUrl: 'templates/tab-reports.html',
        controller: 'ReportsCtrl'
      }
    }
  })

L'onglet de rapports correspondant HTML peut ressembler à:

<ion-view view-title="Reports">
  <ion-content ng-controller="ReportsCtrl">

Cela entraînera également l'exécution du contrôleur deux fois.


1021
2018-03-20 22:08



AngularJS docs - ngController
  Notez que vous pouvez également attacher des contrôleurs au DOM en le déclarant   dans une définition de route via le service $ route. Une erreur commune est de   déclarer le contrôleur à nouveau en utilisant ng-controller dans le modèle   lui-même. Cela provoquera le rattachement et l'exécution du contrôleur   deux fois.

Lorsque vous utilisez ngRoute avec le ng-view directive, le contrôleur est attaché à cet élément dom par défaut (ou ui-view si vous utilisez ui-router). Vous n'aurez donc pas besoin de l'attacher à nouveau dans le modèle.


123
2017-10-02 08:46



Je viens de passer en revue, mais la question était différente de la réponse acceptée. Je laisse vraiment cela ici pour mon avenir, pour inclure les étapes que j'ai traversées pour le réparer.

  1. Supprimer les déclarations de contrôleur redondantes
  2. Vérifier les barres obliques de fin dans les routes
  3. Vérifier ng-ifs
  4. Vérifiez pour tout emballage inutile ng-view appels (j'ai accidentellement laissé dans un ng-view qui enveloppait mon réel ng-view. Cela a entraîné trois appels à mes contrôleurs.)
  5. Si vous êtes sur Rails, vous devez supprimer le turbolinks gemme de votre application.js fichier. J'ai perdu une journée entière à le découvrir. Réponse trouvée ici.
  6. Initialisation de l'application deux fois avec ng-app et avec bootstrap. Combattre le contrôleur exécutant AngularJS deux fois
  7. Lors de l'utilisation de $ compile sur l'élément entier dans la fonction 'link' de la directive qui a aussi son propre contrôleur défini et utilise les rappels de ce contrôleur dans le template via ng-click etc. ici.

62
2018-03-24 18:52



Je veux juste ajouter un cas supplémentaire quand le contrôleur peut init deux fois (ceci est réel pour angular.js 1.3.1):

<div ng-if="loading">Loading...</div>
<div ng-if="!loading">
    <div ng-view></div>
</div>

Dans ce cas, $ route.current sera déjà défini lorsque ng-view sera init. Cela provoque une double initialisation.

Pour le réparer, changez simplement ng-if en ng-show / ng-hide et tout ira bien.


12
2017-11-17 11:08



Aimeriez ajouter pour référence:

L'exécution de code double contrôleur peut également être provoquée en référençant le contrôleur dans une directive qui s'exécute également sur la page.

par exemple.

return {

            restrict: 'A',
            controller: 'myController',
            link: function ($scope) { ....

Lorsque vous avez aussi ng-controller = "myController" dans votre HTML


7
2017-10-28 18:19



En utilisant routeur angulaire avec Angular 1.3+, il y avait un problème à propos de Rendu des vues deux fois sur la transition de route. Cela a entraîné l'exécution de contrôleurs deux fois aussi. Aucune des solutions proposées n'a fonctionné pour moi.

Cependant, mise à jour angular-ui-router de 0.2.11 à 0.2.13 résolu le problème pour moi.


7
2018-04-19 11:25



J'ai déchiré mon application et toutes ses dépendances sur ce problème (détails ici: Application AngularJS initiant deux fois (essayé les solutions habituelles ..))

Et à la fin, tout était la faute du plugin Batarang Chrome.

Résolution en cette réponse:

Je recommande fortement la première chose sur la liste de n'importe qui est de le désactiver par la poste avant de modifier le code.


6
2018-05-07 08:56



J'ai eu le même problème, dans une application simple (sans routage et une simple référence ng-controller) et le constructeur de mon contrôleur a été exécuté deux fois. Enfin, j'ai découvert que mon problème était la déclaration suivante pour auto-bootstrap mon application AngularJS dans ma vue rasoir

<html ng-app="mTest1">

Je l'ai aussi manuellement initialisé en utilisant angular.bootstrap, c'est-à-dire

angular.bootstrap(document, [this.app.name]);

en enlevant l'un d'eux, cela a fonctionné pour moi.


5
2018-01-27 14:33



Si vous savez que votre contrôleur s'exécute involontairement plus d'une fois, essayez de rechercher dans vos fichiers le nom du contrôleur incriminé, ex: search: MyController dans tous les fichiers. Il a probablement été copié-collé dans un autre fichier html / js et vous avez oublié de le changer lorsque vous avez développé ou utilisé ces partiels / contrôleurs. Source: J'ai fait cette erreur


4
2017-08-01 22:49



Dans certains cas, votre directive s'exécute deux fois lorsque vous ne corrigez pas simplement votre directive comme ceci:

<my-directive>Some content<my-directive>

Cela exécutera votre directive deux fois. Il y a aussi un autre cas où votre directive est exécutée deux fois:

assurez-vous de ne pas inclure votre directive dans votre index.html  DEUX FOIS!


4
2017-11-18 10:54