Comprendo che AngularJS esegue il codice due volte, a volte anche di più, come gli eventi di $watch
, il controllo costante degli stati del modello ecc.
Comunque il mio codice:
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); }); //...
Viene eseguito due volte, inserendo 2 record nel mio DB. Sto ancora imparando come ho battuto la testa contro questo per secoli!
Il router dell’app ha specificato la navigazione su MyController
modo:
$routeProvider.when('/', { templateUrl: 'pages/home.html', controller: MyController });
Ma ho avuto anche questo in home.html
:
Questo ha digerito il controller due volte. La rimozione dell’attributo data-ng-controller
dall’HTML ha risolto il problema. In alternativa, il controller:
proprietà potrebbe essere stata rimossa dalla direttiva di routing.
Questo problema appare anche quando si utilizza la navigazione a tabs. Ad esempio, app.js
potrebbe contenere:
.state('tab.reports', { url: '/reports', views: { 'tab-reports': { templateUrl: 'templates/tab-reports.html', controller: 'ReportsCtrl' } } })
La scheda HTML corrispondente potrebbe essere simile a:
Ciò comporterà anche l’esecuzione del controller due volte.
AngularJS docs – ngController
Si noti che è anche ansible colbind i controller al DOM dichiarandolo in una definizione di rotta tramite il servizio $ route. Un errore comune è quello di dichiarare nuovamente il controller utilizzando ng-controller nel modello stesso. Ciò farà sì che il controller venga collegato ed eseguito due volte.
Quando si utilizza ngRoute con la direttiva ng-view
, il controller viene collegato a quell’elemento dom per impostazione predefinita (o ui-view se si utilizza ui-router). Quindi non sarà necessario allegarlo di nuovo nel modello.
L’ho appena esaminato, ma il problema era diverso dalla risposta accettata. Sto davvero lasciando questo qui per il mio futuro io, per includere i passaggi che ho passato per risolverlo.
ng-ifs
ng-view
(mi sono accidentalmente lasciato in una ng-view
che stava avvolgendo la mia attuale ng-view
. Ciò ha comportato tre chiamate ai miei controller.) turbolinks
dal tuo file application.js
. Ho perso un giorno intero per scoprirlo. Trovato risposta qui . Voglio solo aggiungere un altro caso quando il controller può avviare due volte (questo è vero per angular.js 1.3.1):
Loading...
In questo caso $ route.current sarà già impostato quando ng-view verrà avviato. Ciò causa una doppia inizializzazione.
Per risolvere il problema basta cambiare ng-if in ng-show / ng-hide e tutto funzionerà bene.
Vorrei aggiungere per riferimento:
L’esecuzione del codice del controller doppio può anche essere causata facendo riferimento al controller in una direttiva che viene eseguita anche sulla pagina.
per esempio
return { restrict: 'A', controller: 'myController', link: function ($scope) { ....
Quando hai anche ng-controller = “myController” nel tuo HTML
Quando si utilizza angular -ui-router con Angular 1.3+, si è verificato un problema sulle viste di rendering due volte sulla transizione del percorso . Ciò ha comportato anche l’esecuzione di controller due volte. Nessuna delle soluzioni proposte ha funzionato per me.
Tuttavia, l’aggiornamento di angular angular-ui-router
da 0.2.11 a 0.2.13 ha risolto il problema per me.
Ho strappato la mia app e tutte le sue dipendenze a bit su questo problema (dettagli qui: l’ app AngularJS ha avviato due volte (provato le solite soluzioni ..) )
E alla fine, è stata colpa di tutto il plugin di Batarang Chrome.
Risoluzione in questa risposta :
Consiglio vivamente che la prima cosa sulla lista di tutti è disabilitarla per posta prima di modificare il codice.
Ho avuto lo stesso problema, in una semplice app (senza routing e un semplice riferimento al controller ng) e il costruttore del mio controller è stato eseguito due volte. Alla fine, ho scoperto che il mio problema era la seguente dichiarazione di auto-bootstrap della mia applicazione AngularJS nella mia vista Razor
L’ho anche riavviato manualmente usando angular.bootstrap ie
angular.bootstrap(document, [this.app.name]);
così togliendone uno, ha funzionato per me.
Se si sa che il controller viene eseguito non intenzionalmente più di una volta, provare una ricerca attraverso i propri file per il nome del controller che causa l’errore, ad es .: search: MyController attraverso tutti i file. Probabilmente è stato copiato in un altro file html / js e ti sei dimenticato di cambiarlo quando hai iniziato a sviluppare o usare quei partial / controller. Fonte: ho fatto questo errore
In alcuni casi la direttiva viene eseguita due volte quando semplicemente non si corregge la direttiva come in questo modo:
Questo eseguirà la tua direttiva due volte. C’è anche un altro caso spesso quando la tua direttiva viene eseguita due volte:
assicurati di non includere la direttiva nel tuo index.html
DUE VOLTE !
Mi sono grattato la testa su questo problema con AngularJS 1.4 rc build, quindi mi sono reso conto che nessuna delle risposte precedenti era applicabile poiché era stata originata dalla nuova libreria del router per Angular 1.4 e Angular 2 al momento della stesura di questo documento. Pertanto, sto rilasciando una nota qui per chiunque potrebbe utilizzare la nuova libreria di rotte Angular.
Fondamentalmente se una pagina HTML contiene una direttiva ng-viewport
per il caricamento di parti della tua app, facendo clic su un collegamento ipertestuale specificato con ng-link
causerebbe il caricamento del controller di destinazione del componente associato due volte. La sottile differenza è che, se il browser ha già caricato il controller di destinazione, facendo nuovamente clic sullo stesso collegamento ipertestuale invocherà il controller solo una volta.
Non ho ancora trovato una soluzione valida, anche se credo che questo comportamento sia coerente con l’osservazione sollevata da shaunxu , e si spera che questo problema venga risolto nella futura build della nuova libreria di percorsi e insieme alle versioni di AngularJS 1.4.
Nel mio caso, ho trovato due viste usando lo stesso controller.
$stateProvider.state('app', { url: '', views: { "[email protected]": { controller: 'CtrlOne as CtrlOne', templateUrl: 'main/one.tpl.html' }, "[email protected]": { controller: 'CtrlOne as CtrlOne', templateUrl: 'main/two.tpl.html' } } });
Il problema che sto incontrando potrebbe essere tangenziale, ma dato che googling mi ha portato a questa domanda, questo potrebbe essere appropriato. Il problema alza la sua brutta testa per me quando uso UI Router, ma solo quando provo ad aggiornare la pagina con il pulsante di aggiornamento del browser. L’app utilizza l’UI Router con uno stato astratto genitore, quindi i figli vengono esclusi dal genitore. Sulla funzione run()
dell’app, c’è un $state.go('...child-state...')
. Lo stato genitore usa una resolve
e all’inizio pensai che forse un controller figlio è in esecuzione due volte.
Tutto va bene prima che l’URL abbia aggiunto l’hash.
www.someoldwebaddress.org
Quindi una volta che l’url è stato modificato da UI Router,
www.someoldwebaddress.org#/childstate
… e poi quando $stateChangeStart
la pagina con il pulsante di aggiornamento del browser , $stateChangeStart
si $stateChangeStart
due volte e ogni volta punta al childstate
.
La resolve
sullo stato genitore è ciò che sta sparando due volte.
Forse questo è un kludge; a prescindere, sembra che questo mi elimini il problema: nell’area del codice dove viene prima richiamato $stateProvider
, prima controlla se il file window.location.hash è una stringa vuota. Se lo è, tutto è buono; in caso contrario, impostare window.location.hash su una stringa vuota. Quindi sembra che lo $state
cerchi di andare da qualche parte una volta piuttosto che due volte.
Inoltre, se non vuoi fare affidamento sull’esecuzione predefinita e state.go(...)
, puoi provare ad acquisire il valore hash e utilizzare il valore hash per determinare lo stato figlio in cui ti state.go(...)
appena prima dell’aggiornamento della pagina, e aggiungi una condizione all’area nel tuo codice in cui imposti lo state.go(...)
.
Nel mio caso è stato a causa del modello di URL che ho usato
il mio url era come / ui / project /: parameter1 /: parameter2.
Non avevo bisogno del paramerter2 in tutti i casi di cambiamento di stato. Nei casi in cui non avevo bisogno del secondo parametro il mio url sarebbe come / ui / project /: parameter1 /. E così ogni volta che ho avuto un cambiamento di stato avrò il mio controller aggiornato due volte.
La soluzione era impostare parametro2 come stringa vuota e fare il cambiamento di stato.
Ho avuto questa doppia inizializzazione per un motivo diverso. Per alcune transizioni di percorso nella mia applicazione, volevo forzare lo scorrimento verso la parte superiore della pagina (ad esempio, nei risultati di ricerca impaginati … cliccando su successivo dovresti portarti all’inizio di pagina 2).
Ho fatto questo aggiungendo un listener al $rootScope
$on
$viewContentLoaded
che (in base a determinate condizioni) eseguito
$location.hash('top');
Inavvertitamente ciò stava facendo rivalutare le mie rotte e reinizializzare i controllori
Il mio problema era l’aggiornamento dei parametri di ricerca come $location.search('param', key);
puoi leggere di più qui
il controller viene chiamato due volte a causa dell’aggiunta dei parametri nell’URL
Nel mio caso, rinominare il controller con un nome diverso ha risolto il problema.
C’è stato un conflitto tra i nomi dei controller con il modulo ” angular -ui-tree “: ho rinominato il mio controller da “CatalogerTreeController” in ” TreeController ” e quindi questo controller inizia a essere avviato due volte nella pagina in cui è stata usata la direttiva ” ui-tree ” perché questa direttiva usa il controller chiamato ” TreeController “.
Ho avuto lo stesso problema e dopo aver provato tutte le risposte ho finalmente trovato che avevo una direttiva a mio avviso che era legata allo stesso controller.
APP.directive('MyDirective', function() { return { restrict: 'AE', scope: {}, templateUrl: '../views/quiz.html', controller: 'ShowClassController' } });
Dopo aver rimosso la direttiva, il controller ha smesso di essere chiamato due volte. Ora la mia domanda è, come si può usare questa direttiva legata allo scope del controllore senza questo problema?
Ho appena risolto il mio, che in realtà è stato abbastanza deludente. È un’app ibrida ionica, ho usato ui-router v0.2.13. Nel mio caso c’è un lettore di epub (usando epub.js) che riportava continuamente “nessun documento trovato” quando navigo nella mia biblioteca di libri e seleziono qualsiasi altro libro. Quando ho ricaricato il libro del browser veniva reso perfettamente, ma quando ho selezionato un altro libro ho avuto di nuovo lo stesso problema.
La mia soluzione era molto semplice. Ho appena rimosso il reload:true
da $state.go("app.reader", { fileName: fn, reload: true });
nel mio LibraryController
Ho lo stesso problema in [email protected]
, e questo perché la barra in più alla fine della regex route:
.when('/goods/publish/:classId/', option)
a
.when('/goods/publish/:classId', option)
e funziona correttamente.
Per coloro che usano la syntax ControllerAs, basta dichiarare l’etichetta del controller nel $ routeprovider come segue:
$routeprovider .when('/link', { templateUrl: 'templateUrl', controller: 'UploadsController as ctrl' })
o
$routeprovider .when('/link', { templateUrl: 'templateUrl', controller: 'UploadsController' controllerAs: 'ctrl' })
Dopo aver dichiarato $ routeprovider, non fornire il controller come nella vista. Utilizzare invece l’etichetta nella vista.
Ho capito che il mio viene chiamato due volte perché stavo chiamando il metodo due volte dal mio html.
`
La sezione evidenziata stava causando findX () per essere chiamato due volte. Spero che aiuti qualcuno.