Walka z AngularJS wykonującym kontroler dwukrotnie

Rozumiem, że AngularJS przechodzi przez jakiś kod dwa razy, czasami nawet więcej, jak $watch zdarzenia, ciągłe sprawdzanie stanów modelu itp.

Jednak mój kod:

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);
});

//...

Jest wykonywane dwukrotnie, wstawiając 2 Rekordy do mojego DB. Najwyraźniej wciąż się uczę, bo walę głową o to od wieków!

 534
Author: Devid Farinelli, 2013-03-20

24 answers

Router aplikacji podał nawigację do MyController w ten sposób:

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

Ale też miałem to w home.html:

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

To przetrawiło kontroler dwa razy. Usunięcie atrybutu data-ng-controller z HTML rozwiązało problem. Alternatywnie właściwość controller: mogła zostać usunięta z dyrektywy routingu.

Ten problem pojawia się również podczas korzystania z nawigacji z kartami. Na przykład, {[8] } może zawierać:

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

Odpowiednia karta raportów HTML może przypominać:

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

Spowoduje to również dwukrotne uruchomienie kontrolera.

 1053
Author: Greg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-08 05:48:09

AngularJS docs-ngController
Zauważ, że możesz również dołączyć Kontrolery do DOM, deklarując je w definicji trasy poprzez usługę $ route. powszechnym błędem jest zadeklarować kontroler ponownie używając ng-controller w szablonie siebie. Spowoduje to dołączenie i wykonanie kontrolera dwa razy.

Gdy używasz ngRoute z dyrektywą ng-view, kontroler jest domyślnie dołączany do tego elementu dom (lub ui-view jeśli używasz ui-routera). Nie musisz więc ponownie dołączać go do szablonu.

 127
Author: shxfee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-24 16:11:33

Właśnie przez to przechodziłem, ale problem był inny od zaakceptowanej odpowiedzi. Naprawdę zostawiam to dla mojej przyszłości, aby uwzględnić kroki, przez które przeszedłem, aby to naprawić.

  1. Usuwanie zbędnych deklaracji kontrolera
  2. Sprawdź ukośniki w trasach
  3. Sprawdź dla ng-ifs
  4. sprawdź, czy nie ma niepotrzebnego zawijania ng-view połączeń (przypadkowo zostawiłem w ng-view, który zawijał moje rzeczywiste ng-view. Spowodowało to trzy telefony do kontrolerów.)
  5. Jeśli jesteś na Rails, powinieneś usunąć turbolinks gem ze swojego pliku application.js. Zmarnowałem cały dzień, żeby to odkryć. Znaleziono odpowiedź tutaj .
  6. Inicjalizacja aplikacji dwukrotnie za pomocą ng-app i Bootstrap. walka z AngularJS wykonującym kontroler dwa razy
  7. podczas używania $compile na całym elemencie w'link' -funkcji dyrektywy, która również ma własny kontroler zdefiniowany i używa wywołań zwrotnych tego kontrolera w szablonie poprzez ng-click itp. Znaleziono odpowiedź tutaj .
 70
Author: JesseBuesking,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:27

Chcę tylko dodać jeszcze jeden przypadek, gdy kontroler może init dwa razy (jest to rzeczywiste dla angular.js 1.3.1):

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

W tym przypadku $ route.current będzie już ustawiony, gdy ng-view init. To powoduje podwójną inicjalizację.

Aby to naprawić wystarczy zmienić ng-if na ng-show/ng-hide i wszystko będzie działać dobrze.

 14
Author: DontRelaX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-17 11:08:58

Chciałbym dodać dla odniesienia:

Podwójne wykonanie kodu kontrolera może być również spowodowane odwołaniem się do kontrolera w dyrektywie, która również działa na stronie.

Np.

return {

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

Gdy masz również ng-controller= "myController" w HTML

 7
Author: gb2d,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-28 18:19:21

Podczas używania angular-UI-router z Angular 1.3+ wystąpił problem z renderowaniem widoków dwukrotnie przy przejściu trasy . Spowodowało to także dwukrotne wykonanie kontrolerów. Żadne z proponowanych rozwiązań nie zadziałało.

Jednak aktualizacja angular-ui-router z 0.2.11 do 0.2.13 rozwiązała dla mnie problem.

 7
Author: fracz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-19 11:25:14

Rozdarłem moją aplikację i wszystkie jej zależności na kawałki nad tym problemem (szczegóły tutaj: AngularJS aplikacja inicjowanie dwa razy (próbowałem zwykłych rozwiązań..))

I w końcu to wszystko wina wtyczki Batarang Chrome.

Rozdzielczość w ta odpowiedź :

Zdecydowanie polecam pierwszą rzeczą na czyjejś liście jest wyłączenie go w poście przed zmianą kodu.

 6
Author: Lewis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:01

Jeśli wiesz, że twój kontroler nieumyślnie wykonuje więcej niż jeden raz, spróbuj przeszukać pliki pod kątem nazwy kontrolera, np: search: MyController through all files. Prawdopodobnie został skopiowany do innego pliku html / js i zapomniałeś go zmienić, gdy dostałeś się do tworzenia lub używania tych częściowych / kontrolerów. Źródło: popełniłem ten błąd

 5
Author: user3901016,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-01 22:49:28

Miałem ten sam problem, w prostej aplikacji (bez routingu i prostego odniesienia do kontrolera ng) i konstruktor mojego kontrolera działał dwa razy. W końcu dowiedziałem się, że moim problemem była następująca deklaracja auto-bootstrap mojej aplikacji AngularJS w moim widoku Razor

<html ng-app="mTest1">

Uruchomiłem również ręcznie za pomocą angular.bootstrap czyli

angular.bootstrap(document, [this.app.name]);
Więc usunięcie jednego z nich zadziałało.
 5
Author: athina.bikaki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-28 07:02:44

W niektórych przypadkach twoja dyrektywa działa dwa razy, gdy po prostu nie poprawiasz swojej dyrektywy w ten sposób:

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

To uruchomi Twoją dyrektywę dwa razy. Jest też inny częsty przypadek, gdy twoja dyrektywa działa dwa razy:

Upewnij się, że nie uwzględniasz swojej dyrektywy w swoim index.html dwa razy !

 4
Author: pleerock,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-18 10:54:00

Drapałem się po głowie nad tym problemem z AngularJS 1.4 RC build, potem zdałem sobie sprawę, że żadna z powyższych odpowiedzi nie miała zastosowania, ponieważ powstała z nowej biblioteki routerów dla Angular 1.4 i Angular 2 w momencie pisania tego tekstu. Dlatego zostawiam tutaj notatkę dla każdego, kto może korzystać z nowej biblioteki Angular route.

Zasadniczo, jeśli strona html zawiera dyrektywę ng-viewport do ładowania części aplikacji, klikając hiperłącze określone w ng-link spowodowałoby dwukrotne załadowanie kontrolera docelowego powiązanego komponentu. Subtelna różnica polega na tym, że jeśli przeglądarka już załadowała kontroler docelowy, ponowne kliknięcie tego samego hiperłącza wywołałoby kontroler tylko raz.

Nie znalazłem jeszcze realnego obejścia problemu, chociaż uważam, że to zachowanie jest zgodne z obserwacją podniesioną przez shaunxu i mam nadzieję, że problem ten zostanie rozwiązany w przyszłej budowie nowej biblioteki tras i wraz z AngularJS 1.4 wydania.

 2
Author: codeful.element,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-22 22:49:11

W moim przypadku znalazłem dwa widoki za pomocą tego samego kontrolera.

$stateProvider.state('app', {
  url: '',
  views: {
    "viewOne@app": {
      controller: 'CtrlOne as CtrlOne',
      templateUrl: 'main/one.tpl.html'
    },
    "viewTwo@app": {
      controller: 'CtrlOne as CtrlOne',
      templateUrl: 'main/two.tpl.html'
    }
  }
});
 2
Author: Luke Eller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-12 01:36:58

Problem, z którym się spotykam, może być styczny, ale skoro googlowanie doprowadziło mnie do tego pytania, może to być odpowiednie. Problem budzi u mnie brzydką głowę podczas korzystania z routera UI, ale tylko wtedy, gdy próbuję odświeżyć stronę za pomocą przycisku odświeżania przeglądarki. Aplikacja używa routera interfejsu użytkownika ze stanem abstrakcyjnym nadrzędnym, a następnie Stany podrzędne poza rodzicem. W funkcji app run() znajduje się polecenie $state.go('...child-state...'). Stan rodzica używa resolve, i na początku myślałem, że może kontroler dziecka wykonuje dwukrotnie.

Wszystko jest w porządku przed dodaniem hasha do adresu URL.
www.someoldwebaddress.org

Następnie, gdy adres url został zmodyfikowany przez Router UI,
www.someoldwebaddress.org#/childstate

...następnie, gdy odświeżę stronę za pomocą przycisku odświeżania przeglądarki , $stateChangeStart zostanie wywołany dwa razy i za każdym razem wskazuje na childstate.

resolve w stanie nadrzędnym jest to, co odpala się dwukrotnie.

Być może jest to kludge; niezależnie od tego, wydaje się, że eliminuje to problem dla me: w obszarze kodu, w którym $stateProvider jest wywoływane po raz pierwszy, najpierw sprawdź, czy okno .miejsce.hash jest pustym łańcuchem znaków. Jeśli tak, to wszystko jest w porządku; jeśli nie, to ustaw okno .miejsce.hash do pustego łańcucha. Wygląda na to, że $state próbuje gdzieś pójść tylko raz, a nie dwa razy.

Ponadto, jeśli nie chcesz polegać na domyślnych aplikacjach run i state.go(...), Możesz spróbować przechwycić wartość skrótu i użyć jej do określenia stanu potomnego byłeś na tuż przed odświeżeniem strony i Dodaj warunek do obszaru w kodzie, w którym Ustawiłeś state.go(...).

 2
Author: mg1075,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-09 04:51:57

Dla tych, którzy używają składni ControllerAs, po prostu zadeklaruj Etykietę kontrolera w $routeprovider w następujący sposób:

$routeprovider
        .when('/link', {
            templateUrl: 'templateUrl',
            controller: 'UploadsController as ctrl'
        })

Lub

$routeprovider
        .when('/link', {
            templateUrl: 'templateUrl',
            controller: 'UploadsController'
            controllerAs: 'ctrl'
        })

Po zadeklarowaniu $routeprovider nie podawaj kontrolera tak jak w widoku. Zamiast tego użyj etykiety w widoku.

 2
Author: M. Arnold,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-26 06:24:51

W moim przypadku było to spowodowane wzorcem url, którego użyłem

Mój url był jak / UI / project/: parametr1/: parametr2.

Nie potrzebowałem paramerter2 we wszystkich przypadkach zmiany stanu. W przypadkach, gdy nie potrzebowałem drugiego parametru, mój adres url byłby podobny do/ui/project/: parameter1/. I tak za każdym razem, gdy miałem zmianę stanu, mój kontroler będzie odświeżany dwa razy.

Rozwiązaniem było ustawienie parametru2 jako pusty łańcuch i dokonanie zmiany stanu.

 1
Author: Sherin Syriac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-13 13:28:35

Miałem tę podwójną inicjalizację z innego powodu. W przypadku niektórych przejść trasy w mojej aplikacji chciałem wymusić przewijanie do góry strony (np. w paginowanych wynikach wyszukiwania... kliknięcie dalej przeniesie Cię na górę strony 2).

Zrobiłem to dodając słuchacza do $rootScope $on $viewContentLoaded które (na podstawie pewnych warunków) wykonane

$location.hash('top');

Nieumyślnie powodowało to, że moje trasy zostały ponownie ocenione, a kontrolerzy reinitialized

 1
Author: Harry Lime,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-24 16:09:02

Mój problem polegał na aktualizacji parametrów wyszukiwania Tak $location.search('param', key);

Możesz przeczytać więcej na ten temat tutaj

Kontroler wywołany dwukrotnie z powodu dodawania param w adresie url

 1
Author: Gal Bracha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:27

W moim przypadku zmiana nazwy kontrolera na inną rozwiązała problem.

Wystąpił konflikt nazw kontrolerów z modułem "angular-UI-tree": zmieniłem nazwę kontrolera z "CatalogerTreeController" na "TreeController" i wtedy ten kontroler zaczyna być inicjowany dwukrotnie na stronie, na której użyto dyrektywy "UI-tree", ponieważ dyrektywa ta używa kontrolera o nazwie "TreeController"..

 1
Author: AlexDEV.pro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-20 15:16:50

Miałem ten sam problem i po wypróbowaniu wszystkich odpowiedzi w końcu okazało się, że mam dyrektywę, która moim zdaniem była związana z tym samym kontrolerem.

APP.directive('MyDirective', function() {
  return {
    restrict: 'AE',
    scope: {},
    templateUrl: '../views/quiz.html',
    controller: 'ShowClassController'
}
});

Po usunięciu dyrektywy kontroler przestał być wywoływany dwukrotnie. Teraz moje pytanie brzmi, w jaki sposób można wykorzystać tę dyrektywę związaną z zakresem kontrolera bez tego problemu?

 0
Author: Daniel Vilas-Boas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-02 14:09:20

Właśnie rozwiązałem swój, co było dość rozczarowujące. Jego ionic hybrid app, użyłem ui-router v0. 2. 13. W moim przypadku jest czytnik epub (za pomocą epub.js), który stale raportował "nie znaleziono dokumentu" , gdy przejdę do biblioteki moich książek i wybieram dowolną inną książkę. Kiedy przeładować książkę przeglądarka była renderowana doskonale, ale kiedy wybrałem inną książkę ma ten sam problem ponownie.

Moje rozwiązanie było bardzo proste. Właśnie usunąłem reload:true z $state.go("app.reader", { fileName: fn, reload: true }); w moim LibraryController
 0
Author: maksbd19,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-21 13:21:49

Mam ten sam problem w [email protected], a to dlatego, że dodatkowy ukośnik na końcu trasy regex:

.when('/goods/publish/:classId/', option)

Do

.when('/goods/publish/:classId', option)

I działa poprawnie.

 0
Author: B.Ma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-28 09:03:39

Dodaję tu również moją sprawę:

Używałem angular-UI-router z $state.go('new_state', {foo: "foo@bar"})

Po dodaniu encodeURIComponent do parametru problem zniknął: $state.go('new_state', {foo: encodeURIComponent("foo@bar")}).

Co się stało? Znak " @ " w wartości parametru nie jest dozwolony w adresach URL. W konsekwencji angular-ui-router dwukrotnie stworzył mój kontroler: podczas pierwszego tworzenia przeszedł oryginalny "foo@bar", podczas drugiego tworzenia przekazywał zakodowaną wersję"foo%40bar". Once I jawnie zakodowany parametr, jak pokazano powyżej, problem zniknął.
 0
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-17 12:52:15

Mój problem był naprawdę trudny do wyśledzenia. Ostatecznie problem wystąpił, gdy strona internetowa miała brakujące obrazy. W src brakowało adresu Url. Działo się to na kontrolerze sieciowym MVC 5. Aby rozwiązać ten problem, dodałem przezroczyste obrazy, gdy nie jest dostępny prawdziwy obraz.

<img alt="" class="logo" src="">
 0
Author: Dumber_Texan2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-06 16:12:17

Zorientowałem się, że moja jest wywoływana dwa razy, ponieważ wywoływałem metodę dwa razy z mojego html.

`<form class="form-horizontal" name="x" ng-submit="findX() novalidate >
 <input type="text"....>
 <input type="text"....>
 <input type="text"....>
 <button type="submit" class="btn btn-sm btn-primary" ng-click="findX()"
</form>`

Wyróżniona sekcja powodowała dwukrotne wywołanie funkcji findX (). Mam nadzieję, że to komuś pomoże.

 -1
Author: Nandu Prajapati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-26 11:04:48