change angularjs

angularjs - change - ng-href angular 5



Combatiendo a AngularJS ejecutando el controlador dos veces. (22)

Entiendo que AngularJS ejecuta un código dos veces, a veces incluso más, como $watch eventos de $watch , comprobando constantemente los estados de los modelos, etc.

Sin embargo mi código:

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

Se ejecuta dos veces, insertando 2 registros en mi DB. ¡Claramente todavía estoy aprendiendo, ya que me he estado golpeando la cabeza contra esto durante años!


AngularJS docs - ngController
Tenga en cuenta que también puede adjuntar controladores al DOM declarándolo en una definición de ruta a través del servicio $ route. Un error común es declarar el controlador nuevamente usando ng-controller en la propia plantilla. Esto hará que el controlador se conecte y ejecute dos veces.

Cuando usa ngRoute con la directiva ng-view , el controlador se adjunta a ese elemento dom por defecto (o ui-view si usa ui-router). Así que no necesitarás adjuntarlo nuevamente en la plantilla.


Acabo de pasar por esto, pero el problema era diferente de la respuesta aceptada. Realmente estoy dejando esto aquí para mi futuro yo, para incluir los pasos que seguí para solucionarlo.

  1. Eliminar declaraciones de controlador redundantes
  2. Consulta las barras inclinadas en las rutas.
  3. Compruebe si hay ng-ifs
  4. Compruebe si hay llamadas innecesarias de ng-view ajuste (accidentalmente había dejado en una ng-view que estaba envolviendo mi ng-view real. Esto dio lugar a tres llamadas a mis controladores.)
  5. Si está en Rails, debe eliminar la gema turbolinks de su archivo application.js . Perdí un día entero para descubrir eso. Encontré la respuesta here .
  6. Inicializando la aplicación dos veces con ng-app y con bootstrap. Combatiendo a AngularJS ejecutando el controlador dos veces.
  7. Cuando se usa $ compile en el elemento completo en la función ''link'' de la directiva, también tiene su propio controlador definido y utiliza las devoluciones de llamada de este controlador en la plantilla mediante ng-click, etc. Encontrará la respuesta here .

Acabo de resolver el mío, que en realidad fue bastante decepcionante. Es una aplicación híbrida iónica, he usado ui-router v0.2.13. En mi caso, hay un lector de epub (que usa epub.js) que continuamente informaba "no se encontró ningún documento" una vez que navego a la biblioteca de mis libros y selecciono cualquier otro libro. Cuando volví a cargar, el navegador se estaba procesando a la perfección, pero cuando seleccioné otro libro, volví a tener el mismo problema.

Mi solución fue muy simple. Acabo de eliminar reload:true de $state.go("app.reader", { fileName: fn, reload: true }); en mi LibraryController la LibraryController


Al analizar este problema con AngularJS 1.4 rc build, no me di cuenta de que ninguna de las respuestas anteriores era aplicable, ya que se originó en la nueva biblioteca de enrutadores para Angular 1.4 y Angular 2 en el momento de escribir este artículo. Por lo tanto, estoy enviando una nota aquí para cualquier persona que pueda estar usando la nueva biblioteca de rutas angulares.

Básicamente, si una página html contiene una directiva ng-viewport para cargar partes de su aplicación, al hacer clic en un hipervínculo especificado con ng-link , el controlador de destino del componente asociado se cargará dos veces. La diferencia sutil es que, si el navegador ya ha cargado el controlador de destino, al volver a hacer clic en el mismo hipervínculo solo se invocará al controlador una vez.

Aún no he encontrado una solución viable, aunque creo que este comportamiento es consistente con la observación planteada por shaunxu , y espero que este problema se resuelva en la futura compilación de la nueva biblioteca de rutas y junto con las versiones de AngularJS 1.4.



El enrutador de la aplicación especificó la navegación a MyController así:

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

Pero también tuve esto en home.html :

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

Esto digiere el controlador dos veces. Eliminar el atributo data-ng-controller del HTML resolvió el problema. Alternativamente, la propiedad controller: podría haberse eliminado de la directiva de enrutamiento.

Este problema también aparece cuando se utiliza la navegación con pestañas. Por ejemplo, app.js podría contener:

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

La pestaña de informes correspondiente a HTML podría parecerse a:

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

Esto también resultará en ejecutar el controlador dos veces.


El problema que estoy encontrando podría ser tangencial, pero como la búsqueda en Google me llevó a esta pregunta, esto podría ser apropiado. El problema me asusta cuando uso el enrutador UI, pero solo cuando intento actualizar la página con el botón de actualización del navegador. La aplicación utiliza el enrutador UI con un estado abstracto primario y, a continuación, el estado secundario se desconecta del padre. En la función run() , hay un $state.go(''...child-state...'') . El estado principal utiliza una resolve , y al principio pensé que quizás un controlador secundario se está ejecutando dos veces.

Todo está bien antes de que se haya agregado el hash a la URL.
www.someoldwebaddress.org

Luego, una vez que la url ha sido modificada por el enrutador UI,
www.someoldwebaddress.org#/childstate

... y luego cuando actualizo la página con el botón de actualización del navegador , $stateChangeStart dispara dos veces, y cada vez apunta al estado del childstate .

La resolve en el estado principal es lo que se dispara dos veces.

Tal vez esto es un embrollo; independientemente, esto parece eliminar el problema para mí: en el área del código donde se invoca por primera vez $stateProvider , primero verifique si window.location.hash es una cadena vacía. Si lo es, todo es bueno; si no lo está, entonces establezca window.location.hash en una cadena vacía. Entonces parece que el $state solo intenta ir a algún lugar una vez en lugar de dos veces.

Además, si no desea confiar en la run predeterminada de la aplicación y en state.go(...) , puede intentar capturar el valor hash y usar el valor hash para determinar el estado secundario en el que se encontraba justo antes de la actualización de la página. y agregue una condición al área en su código donde estableció el state.go(...) .


En algunos casos, su directiva se ejecuta dos veces cuando simplemente no corrige el cierre de su directiva de esta manera:

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

Esto ejecutará su directiva dos veces. También hay otro caso a menudo cuando su directiva se ejecuta dos veces:

asegúrese de no incluir su directiva en su index.html ¡ DOS VECES !


En mi caso fue por el patrón de url que usé

mi url era como / ui / project /: Parameter1 /: Parameter2.

No necesitaba paramerter2 en todos los casos de cambio de estado. En los casos en que no necesitaba el segundo parámetro, mi url sería como / ui / project /: parameters1 /. Y así, siempre que haya un cambio de estado, actualizaré mi controlador dos veces.

La solución fue establecer el parámetro 2 como una cadena vacía y hacer el cambio de estado.


En mi caso, cambiar el nombre del controlador a un nombre diferente resolvió el problema.

Hubo un conflicto de nombres de controladores con el módulo " angular-ui-tree ": cambié el nombre de mi controlador de "CatalogerTreeController" a " TreeController " y luego este controlador comienza a iniciarse dos veces en la página donde se usa la directiva " ui-tree " porque esta directiva utiliza el controlador llamado " TreeController ".


En mi caso, encontré dos vistas usando el mismo controlador.

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


He tenido esta doble inicialización por una razón diferente. Para algunas transiciones de ruta en mi aplicación, quería forzar el desplazamiento hacia la parte superior de la página (p. Ej., En los resultados de búsqueda paginados ... al hacer clic en el siguiente debería ir al principio de la página 2).

Hice esto agregando un oyente al $rootScope $on $viewContentLoaded que (basado en ciertas condiciones) ejecutó

$location.hash(''top'');

Inadvertidamente, esto hizo que mis rutas se reevaluaran y que los controladores se reiniciaran.


Me di cuenta de que el mío se llamaba dos veces porque estaba llamando al método dos veces desde mi 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>`

La sección resaltada causaba que se llamara a findX () dos veces. Espero que ayude a alguien.



Para aquellos que usan la sintaxis de ControllerAs, simplemente declare la etiqueta del controlador en el $ routeprovider de la siguiente manera:

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

o

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

Después de declarar el $ routeprovider, no suministre el controlador como en la vista. En su lugar, utilice la etiqueta en la vista.


Quisiera agregar para referencia:

La ejecución del código del controlador doble también puede ser causada al hacer referencia al controlador en una directiva que también se ejecuta en la página.

p.ej

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

Cuando también tiene ng-controller = "myController" en su HTML



Si sabe que su controlador se está ejecutando involuntariamente más de una vez, intente buscar el nombre del controlador infractor en sus archivos, por ejemplo, buscar: MyController en todos los archivos. Probablemente se copió y pegó en algún otro archivo html / js y se olvidó de cambiarlo cuando se desarrolló o usó esos parciales / controladores. Fuente: Cometí este error.


Solo desea agregar un caso más cuando el controlador pueda iniciarse dos veces (esto es real para angular.js 1.3.1):

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

En este caso, $ route.current ya estará configurado cuando ng-view iniciará. Eso causa doble inicialización.

Para solucionarlo, simplemente cambie ng-if a ng-show / ng-hide y todo funcionará bien.


Tengo el mismo problema en [email protected] , y esto se debe a que la barra adicional al final de la ruta de expresiones regulares:

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

a

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

y funciona correctamente.


Tuve el mismo problema y, después de probar todas las respuestas, finalmente encontré que tenía una directiva en mi opinión que estaba vinculada al mismo controlador.

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

Después de eliminar la directiva, el controlador dejó de ser llamado dos veces. Ahora mi pregunta es, ¿cómo se puede usar esta directiva vinculada al ámbito del controlador sin este problema?


Tuve el mismo problema, en una aplicación simple (sin enrutamiento y una simple referencia de ng-controller) y el constructor de mi controlador se ejecutó dos veces. Finalmente, descubrí que mi problema era la siguiente declaración para arrancar automáticamente mi aplicación AngularJS en mi vista Razor

<html ng-app="mTest1">

También lo he arrancado manualmente usando angular.bootstrap ie

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

Así que eliminando uno de ellos, funcionó para mí.