什么是Angular ui-router生命周期? (用于调试静默错误)

时间:2013-12-23 14:42:43

标签: angularjs angular-ui-router

我发现的最好的是http://www.ng-newsletter.com/posts/angular-ui-router.html。它不会像$stateChangeStartexampleState.onEnterexampleState.resolveexampleState.templateProvider触发的顺序那样深。

一个很好的答案格式是干净的。类似的东西:

  1. 状态foo的初始页面加载:

    1. 角度生命周期第1步
    2. UI路由器生命周期第1步
    3. UI路由器生命周期解决发生
    4. UI路由器生命周期onEnter fires
    5. 角度生命周期第2步
  2. 状态更改 foo - >的

    1. $stateChangeStart事件触发
    2. foo onExit触发
    3. bar onEnter消防
    4. templateUrl获取模板
    5. UI路由器在摘要循环中(或任何地方)插回Angular生命周期。
  3. 嵌套状态

  4. 多个命名视图:

  5. ui-sref点击了

  6. 等等......谢谢!

    编辑:调试功能提供了足够的洞察力以满足需要。有关摘要,请参阅我的answer below

5 个答案:

答案 0 :(得分:171)

经过一些实验,我想出了如何充分了解生命周期以调试我的应用程序并了解正在发生的事情。使用所有事件,包括onEnter,onExit,stateChangeSuccess,来自here的viewContentLoaded,给了我一个很好的画面,说明事情发生的时间比我的代码更灵活,更具体,而不是写出来的生命周期。在app模块的“运行”功能中,我放置了:

如果我在第一次使用Angular和UI路由器时开始使用它,这段代码可以节省我几天的时间和困惑。 UI路由器需要一个“调试”模式,默认情况下启用它。

$rootScope.$on('$stateChangeStart',function(event, toState, toParams, fromState, fromParams){
  console.log('$stateChangeStart to '+toState.name+'- fired when the transition begins. toState,toParams : \n',toState, toParams);
});
$rootScope.$on('$stateChangeError',function(event, toState, toParams, fromState, fromParams, error){
  console.log('$stateChangeError - fired when an error occurs during transition.');
  console.log(arguments);
});
$rootScope.$on('$stateChangeSuccess',function(event, toState, toParams, fromState, fromParams){
  console.log('$stateChangeSuccess to '+toState.name+'- fired once the state transition is complete.');
});
$rootScope.$on('$viewContentLoading',function(event, viewConfig){
   console.log('$viewContentLoading - view begins loading - dom not rendered',viewConfig);
});

/* $rootScope.$on('$viewContentLoaded',function(event){
     // runs on individual scopes, so putting it in "run" doesn't work.
     console.log('$viewContentLoaded - fired after dom rendered',event);
   }); */

$rootScope.$on('$stateNotFound',function(event, unfoundState, fromState, fromParams){
  console.log('$stateNotFound '+unfoundState.to+'  - fired when a state cannot be found by its name.');
  console.log(unfoundState, fromState, fromParams);
});

答案 1 :(得分:28)

我使用了@ Adam的解决方案并将其包装到一个服务中,这样我就可以在我的应用程序中打开和关闭调试(打印到控制台)。

在模板中:

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

在控制器中:

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

或者只是打开它:

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

服务:

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

答案 2 :(得分:2)

ui-router如何管理默认$ location提供程序旁边的URL并不清楚,这里添加更多调试代码。希望它会有所帮助。这些来自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);
});

答案 3 :(得分:2)

我需要调试我使用的ui-router以及ui-router-extras粘性状态包。我发现粘性状态具有内置调试功能,有助于解决我的问题。它记录有关状态转换的信息以及不活动/活动的信息。

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

sudo

答案 4 :(得分:1)

UI路由器已使用Transition Hooks进行了更新。

使用$ transition $ service访问onError钩子并捕获错误。

挂钩清单:

  • onBefore - 过渡即将开始
  • onStart - 转换已开始
  • onExit - (状态事件)退出所有退出状态
  • onRetain - (状态事件)保留任何保留状态
  • onEnter - (状态事件)输入任何进入状态
  • onFinish - 过渡即将结束
  • onSuccess - 转换已完成且成功或出错。
  • onError - 转换完成,成功或出错。

您可以查看概述以了解转型:https://ui-router.github.io/guide/transitions

请参阅Transition Hook事件的文档:https://ui-router.github.io/guide/transitionhooks