AngularJS使用Resolver实现状态重定向失败问题排查
解决AngularJS路由Resolve中重定向不生效的问题
看起来你在AngularJS路由的resolve里实现重定向时遇到了问题——控制台能打印指定日志,但跳转始终没效果,我来帮你排查问题并给出修复方案。
核心问题分析
你的代码有两个关键问题导致重定向失效:
Resolver的执行逻辑未正确对接路由流程
你把Resolver实现为service类,并且在构造函数里直接调用了_resolve()方法,但AngularJS的路由resolve需要的是返回Promise的函数(或Promise本身)。当前你的service实例并没有把_resolve()返回的Promise暴露给路由的resolve流程,所以Angular无法正确等待这个异步逻辑完成。重定向时的Promise处理错误
当你需要跳转到其他路由时,调用了deferred.resolve(),这会告诉Angular“当前resolve逻辑成功完成”,路由会继续加载homepage状态,后续的$state.go()会被当前路由的加载流程中断或覆盖。正确的做法是在需要重定向时reject这个Promise,阻止当前路由的加载,确保跳转能正常生效。
修复后的代码
1. 修改Resolver类
把_resolve改成公共方法,移除构造函数里的自动调用,让路由的resolve主动触发逻辑并获取Promise:
const AngularInjected = require('app_core/angular-injected'); class HomePageFormSeoResolver extends AngularInjected { static get $inject() { return [ 'Logger', 'CONFIG', '$location', '$state', '$q' ]; } constructor(...dependencies) { super(...dependencies); // 移除构造函数里的_resolve调用,让路由resolve主动触发逻辑 } /** * 检查URL参数formSeo是否为yes,决定是否重定向 */ resolve() { const deferred = this.deps.$q.defer(); const get_params = this.deps.$location.search(); if (get_params.formSeo !== undefined && get_params.formSeo === 'yes') { console.log('Here we are !!!!'); // 重定向前reject Promise,阻止当前路由加载 deferred.reject('redirecting'); this.deps.$state.go('signup-confirmation'); } else { deferred.resolve(); } return deferred.promise; } } module.exports = { init: ngModule => { ngModule.service( 'HomePageFormSeoResolver', HomePageFormSeoResolver ); } };
2. 修改路由状态配置
在resolve里显式调用Resolver的resolve方法,确保返回Promise给路由流程:
const defaultTemplate = require('path-to-homepage-template/homepage.tpl'); module.exports = { states: [ { state: 'homepage', config: { url: '/', templateUrl: defaultTemplate, title: 'homepage', controller: 'HomepageController', controllerAs: 'homepage', resolve: { // 显式注入Resolver并调用其resolve方法 HomePageFormSeoResolver: ['HomePageFormSeoResolver', function(resolver) { return resolver.resolve(); }] } } } ] };
补充说明
- 当你reject Promise时,AngularJS会默认抛出路由错误。如果不想看到无关的错误日志,可以在全局路由错误处理里忽略
redirecting这个特定的reject信息。 - 你也可以把Resolver改成
factory,直接返回执行逻辑的函数,这样路由配置会更简洁:
对应的路由resolve可以简化为:// Factory版本的Resolver module.exports = { init: ngModule => { ngModule.factory('HomePageFormSeoResolver', ['Logger', 'CONFIG', '$location', '$state', '$q', function(Logger, CONFIG, $location, $state, $q) { return function() { const deferred = $q.defer(); const get_params = $location.search(); if (get_params.formSeo === 'yes') { console.log('Here we are !!!!'); deferred.reject('redirecting'); $state.go('signup-confirmation'); } else { deferred.resolve(); } return deferred.promise; } } ]); } };resolve: { HomePageFormSeoResolver: 'HomePageFormSeoResolver' }
这样修改后,当URL中包含?formSeo=yes时,应该就能正常跳转到signup-confirmation状态了。
内容的提问来源于stack exchange,提问作者KodeFor.Me
相关产品推荐
相关产品推荐

