2013-12-23 5 views
64

Das beste, was ich gefunden habe, ist http://www.ng-newsletter.com/posts/angular-ui-router.html. Es geht nicht so tief wie zum Beispiel die Reihenfolge, in der $stateChangeStart, exampleState.onEnter, exampleState.resolve und exampleState.templateProvider feuern.Was ist der angulare UI-Router-Lebenszyklus? (zum Debuggen stiller Fehler)

Ein tolles Antwortformat wäre sauber. Etwas wie:

  1. Initial Pageload staatlicher foo:

    1. Angular Lebenszyklus Schritt 1
    2. UI-Router Lifecycle Schritt 1
    3. UI-Router Lifecycle löst auftreten
    4. UI-Router Lifecycle onEnter Brände
    5. Winkellebenszyklus Schritt 2
  2. Zustandswechsel foo ->bar

    1. $stateChangeStart Ereignis ausgelöst wird
    2. fooonExit Feuer
    3. baronEnter Fires
    4. templateUrl wird die Vorlage
    5. Der UI-Router wird wieder in den Angular-Lebenszyklus in der Digest-Schleife (oder wo auch immer) eingefügt.
  3. Nested Staaten

  4. Multiple benannte Ansichten:

  5. ui-sref geklickt

Etc ... Danke!

EDIT: Debugging-Funktionen zur Verfügung gestellt genug Einblick, um die Notwendigkeit zu erfüllen. Siehe meine answer below für ein Snippet.

+0

haben Sie hier: https://github.com/angular-ui/ui-router#resources – luksch

+1

Danke. Ja. Viele Male. Das Problem, das diese Frage aufzeigte, versuchte, eine aufgelöste Variable in templateProvider zu verwenden. Gemäß der ausführlichen Anleitung hat templateProvider Zugriff auf Locals. Wenn eine Auflösungsvariable verwendet wird, schlägt es automatisch fehl. Das Setzen eines Haltepunkts in templateProvider hat nicht funktioniert, weil der Fehler irgendwann davor aufgetreten ist. Wann war unklar. Da der Lebenszyklus nicht bekannt war, war es schwierig zu wissen, welcher Schritt vor templateProvider stattgefunden hat, um dort einen Haltepunkt zu setzen. Diese Frage soll mir helfen, alle anderen Silent-Fehler-Probleme zu debuggen. – Adam

+0

Ich verstehe jetzt besser. Das ist mir noch nicht aufgefallen. Aber meine Verwendung der Ui-Route-Sache ist ziemlich simpel. jetzt bin ich auch interessiert. +1 – luksch

Antwort

165

Nach einigen Experimenten habe ich herausgefunden, wie man den Lebenszyklus gut genug sieht, um meine App zu debuggen und ein Gefühl dafür zu bekommen, was passiert. Die Verwendung aller Ereignisse, einschließlich onEnter, onExit, stateChangeSuccess, viewContentLoaded von here, gab mir ein anständiges Bild davon, wann die Dinge auf eine Art und Weise ablaufen, die flexibler und spezifischer für meinen Code ist als ein ausgeschriebener Lebenszyklus. In der "run" -Funktion des App-Moduls platzierte ich:

Dieser Code hätte mir Tage der Zeit und Verwirrung erspart, wenn ich ihn anfing, als ich anfing mit Angular und UI-Router. UI-Router benötigt einen "Debug" -Modus, der dies standardmäßig aktiviert.

+11

Vielen Dank für das Teilen! Ich hasse es, leere Seiten mit dem Router zu bekommen und keine Ahnung zu haben, was schiefgelaufen ist ... – Kevin

+1

Adam, du bist eine lebende Legende. Danke dafür. –

+0

Froh, dass Sie es hilfreich fanden! – Adam

2

Wie ui-Router URLs neben dem Standard-$ -Standort-Provider verwaltet, ist nicht klar, so dass hier mehr Debug-Code hinzugefügt wird. Hoffentlich wird es hilfreich sein.Diese sind von https://github.com/ryangasparini-wf/angular-website-routes

$scope.$on('$routeChangeError', function(current, previous, rejection) { 
    console.log("routeChangeError", currrent, previous, rejection); 
}); 

$scope.$on('$routeChangeStart', function(next, current) { 
    console.log("routeChangeStart"); 
    console.dir(next); 
    console.dir(current); 
}); 

$scope.$on('$routeChangeSuccess', function(current, previous) { 
    console.log("routeChangeSuccess"); 
    console.dir(current); 
    console.dir(previous); 
}); 

$scope.$on('$routeUpdate', function(rootScope) { 
    console.log("routeUpdate", rootScope); 
}); 
28

I @ Adams Lösung nahm und wickeln Sie es in einen Dienst, so kann ich wechseln Debuggen (Druck auf die Konsole) ein und aus aus meiner Anwendung.

In der Vorlage:

<button ng-click="debugger.toggle()">{{debugger.active}}</button> 

In der Steuerung:

function($scope, PrintToConsole){ $scope.debugger = PrintToConsole; } 

Oder es einfach nur einschalten:

angular.module('MyModule', ['ConsoleLogger']) 
.run(['PrintToConsole', function(PrintToConsole) { 
    PrintToConsole.active = true; 
}]); 

den Service:

angular.module("ConsoleLogger", []) 
.factory("PrintToConsole", ["$rootScope", function ($rootScope) { 
    var handler = { active: false }; 
    handler.toggle = function() { handler.active = !handler.active; }; 
    $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) { 
     if (handler.active) { 
      console.log("$stateChangeStart --- event, toState, toParams, fromState, fromParams"); 
      console.log(arguments); 
     }; 
    }); 
    $rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) { 
     if (handler.active) { 
      console.log("$stateChangeError --- event, toState, toParams, fromState, fromParams, error"); 
      console.log(arguments); 
     }; 
    }); 
    $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) { 
     if (handler.active) { 
      console.log("$stateChangeSuccess --- event, toState, toParams, fromState, fromParams"); 
      console.log(arguments); 
     }; 
    }); 
    $rootScope.$on('$viewContentLoading', function (event, viewConfig) { 
     if (handler.active) { 
      console.log("$viewContentLoading --- event, viewConfig"); 
      console.log(arguments); 
     }; 
    }); 
    $rootScope.$on('$viewContentLoaded', function (event) { 
     if (handler.active) { 
      console.log("$viewContentLoaded --- event"); 
      console.log(arguments); 
     }; 
    }); 
    $rootScope.$on('$stateNotFound', function (event, unfoundState, fromState, fromParams) { 
     if (handler.active) { 
      console.log("$stateNotFound --- event, unfoundState, fromState, fromParams"); 
      console.log(arguments); 
     }; 
    }); 
    return handler; 
}]); 
+0

Dank Endy, Diese Fabrik ist sehr nützlich. – Vijey

+3

Ich denke, es ist auch besser, $ log zu injizieren, und dann können wir den Dienst sogar noch weiter zu Zeilen wie diesem vereinfachen: $ log.debug ("$ viewContentLoading --- event, viewConfig", Argumente); –

2

Ich musste den UI-Router debuggen, den ich zusammen mit dem UI-Router-Extras Sticky-State-Paket verwendet habe. Ich habe festgestellt, dass die Sticky-Zustände ein Debugging eingebaut haben, das mir geholfen hat, mein Problem zu lösen. Es protokolliert Informationen über die Zustandsübergänge und welche inaktiv/aktiv sind.

https://christopherthielen.github.io/ui-router-extras/#/sticky

angular.module('<module-name>').config(function ($stickyStateProvider) { 
    $stickyStateProvider.enableDebug(true); 
}); 
Verwandte Themen