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

Posted

技术标签:

【中文标题】Angular ui-router 生命周期是啥? (用于调试静默错误)【英文标题】:What is the Angular ui-router lifecycle? (for debugging silent errors)Angular ui-router 生命周期是什么? (用于调试静默错误) 【发布时间】:2014-01-11 19:16:29 【问题描述】:

我找到的最好的是http://www.ng-newsletter.com/posts/angular-ui-router.html。它没有像$stateChangeStartexampleState.onEnterexampleState.resolveexampleState.templateProvider 着火的顺序那样深入。

一个很好的答案格式应该是干净的。比如:

    状态 foo 的初始页面加载:

      Angular 生命周期步骤 1 UI 路由器生命周期步骤 1 UI 路由器生命周期解析发生 UI 路由器生命周期 onEnter 触发 Angular 生命周期第 2 步

    状态改变 foo -> bar

      $stateChangeStart 事件触发 foo onExit 触发 酒吧 onEnter Fires templateUrl 获取模板 UI 路由器在摘要循环(或任何地方)中重新插入 Angular 生命周期。

    嵌套状态

    多个命名视图:

    点击了ui-sref

等等...谢谢!

编辑:调试功能提供了足够的洞察力来满足需求。请参阅我的answer below 获取 sn-p。

【问题讨论】:

你看这里了吗:github.com/angular-ui/ui-router#resources 谢谢。是的。多次。提示此问题的问题是尝试在 templateProvider 中使用已解析的变量。根据深入指南,templateProvider 可以访问本地。如果使用解析变量,它会静默失败。在 templateProvider 中设置断点不起作用,因为失败发生在此之前的某个时间。什么时候不清楚。不知道生命周期,很难知道在 templateProvider 之前发生了什么步骤以便在那里设置断点。所以这个问题是为了帮助我调试出现的任何其他静默失败问题。 我现在明白了。我还没有遇到过这个。但是,我对 ui-route 的使用非常简单。现在我也很感兴趣。 +1 【参考方案1】:

经过一些试验,我想出了如何深入了解生命周期以调试我的应用程序并了解正在发生的事情。使用所有事件,包括 onEnter、onExit、stateChangeSuccess、来自here 的 viewContentLoaded,让我清楚地了解了事情何时以一种比写出的生命周期更加灵活和特定于我的代码的方式发生。在app模块的“run”函数中,我放置了:

如果我在第一次开始使用 Angular 和 UI-router 时就开始使用它,那么这段代码会节省我几天的时间和困惑。 UI-router 需要一个“调试”模式,默认启用此功能。

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

【讨论】:

非常感谢分享!我讨厌路由器出现空白页问题并且不知道出了什么问题... 亚当,你是一个活生生的传奇。谢谢你。 很高兴您发现它有帮助! 这就是@Adam应用模块的运行函数的意思:angular.module('MyModule').run(['$rootScope',function($rootScope) // put the event handlers here ]); “如果我在第一次使用 Angular 和 UI-router 时就开始使用它,那么这段代码会为我节省几天的时间和困惑。” - 这就是文档的用途。 Angular 在这方面需要做更多的工作。【参考方案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】:

我采用了@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;
]);

【讨论】:

谢谢恩迪,这个工厂很有用。 我认为注入 $log 也更好,然后我们可以将服务进一步简化为这样的行: $log.debug("$viewContentLoading --- event, viewConfig", arguments); 【参考方案4】:

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

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

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

【讨论】:

【参考方案5】:

UI 路由器已使用转换挂钩进行了更新。

使用 $transition$ 服务访问 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

【讨论】:

以上是关于Angular ui-router 生命周期是啥? (用于调试静默错误)的主要内容,如果未能解决你的问题,请参考以下文章

Ionic 4 迁移:Ionic 3 生命周期事件/导航守卫的 Angular 等价物是啥?

Angular 生命周期钩子,让你掌控每个关键时刻!

Angular 中的 API 调用和生命周期方法

springbean的生命周期是啥?

bean生命周期的4个阶段是啥?

vue生命周期是啥,有啥作用