540 votes

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

Je comprends qu'AngularJS exécute certains codes deux fois, parfois même plus, par exemple $watch les événements, la vérification constante des é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, insérant 2 enregistrements dans ma base de données. Je suis manifestement encore en train d'apprendre, car cela fait des années que je me cogne la tête contre ce problème !

106 votes

Si votre contrôleur s'exécute deux fois, vérifiez que vous n'initialisez pas deux fois votre application Angular (en l'initialisant automatiquement avec ng-app et avec bootstrap manuel). Vérifiez également si vous avez attaché votre contrôleur à plusieurs éléments (avec ng-controller).

7 votes

Pouvez-vous expliquer ce que vous entendez par "et avec bootstrap manuel" ?

2 votes

1056voto

Greg Points 8549

Le routeur d'applications a spécifié la navigation vers MyController así:

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

Mais j'avais aussi ceci dans home.html :

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

Cela a digéré le contrôleur deux fois. En retirant le data-ng-controller de l'HTML a résolu le problème. Alternativement, l'attribut controller: aurait 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'
      }
    }
  })

Le HTML de l'onglet Rapports correspondant pourrait ressembler :

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

Cela aura également pour conséquence de faire fonctionner le contrôleur deux fois.

4 votes

Cela semble être le meilleur endroit pour laisser cette question, après de nombreuses heures à passer mon code au peigne fin, ne me demandez pas comment, mais quand je modifie <div ng-view>... a <div class="ng-view">... ce problème s'est arrêté pour moi. Je n'ai jamais rencontré ce comportement auparavant, mais peut-être que quelqu'un d'autre le rencontre aussi.

5 votes

Vous trouverez une bonne explication à ce sujet dans les documents relatifs à ngController, docs.angularjs.org/api/ng/directive/ngController

1 votes

Existe-t-il un moyen de déclarer un contrôleur dans la route, puis un autre contrôleur sur la page html elle-même ? Comment s'assurer que les deux fonctionnent et qu'il n'y a pas de conflits ? Ou est-ce inutile ?

129voto

Shafee Points 861

Documentation sur AngularJS - 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 courante consiste à déclarer à nouveau le contrôleur en utilisant ng-controller dans le modèle lui-même. Le contrôleur est alors attaché et exécuté deux fois. deux fois.

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

0 votes

Réponse dupliquée. L'auteur a déjà répondu en disant la même chose. Il suffit de faire défiler vers le bas jusqu'à la fin de la page.

4 votes

J'ai trouvé déroutant que l'auteur l'ait présenté comme une note annexe alors que c'est manifestement la façon correcte de procéder. La citation de la documentation répond clairement à la question. Et je suis sûr que beaucoup trouveraient le lien vers le document utile.

0 votes

Cela a résolu mon problème de double exécution du contrôleur. Tout ce que j'ai fait, c'est supprimer le ng-controller dans le modèle et maintenant il ne s'exécute qu'une fois.

7voto

grx Points 2096

Je voudrais ajouter pour référence :

La double exécution du code du contrôleur peut également être causée par la référence au 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 également ng-controller="myController" dans votre HTML

0 votes

Quelle est la solution à ce problème ?

1 votes

N'utilisez que l'un ou l'autre.

5voto

user3901016 Points 1

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 en question, par exemple : search : MonContrôleur dans tous les fichiers. Il est probable qu'il a été copié-collé dans un autre fichier html/js et que vous avez oublié de le modifier lorsque vous avez développé ou utilisé ces contrôleurs partiels. Source : J'ai fait cette erreur

2voto

user3906109 Points 21

De plus, ne faites pas l'erreur stupide d'inclure le script d'angular deux fois comme je l'ai fait. Exemple :

Mon modèle layout.jade

!!!
html.js.csstransforms3d(ng-app="myApp")
  head
  // more code
  script(src='js/lib/angular/angular.js')

Mon modèle index.jade

extends layout
block body
  // more code
  div.main-wrap(ng-view)
  script(src='js/lib/angular/angular.js')

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X