AngularJS自定义Route Provider报错:未知提供者及when方法异常
排查AngularJS自定义Route Provider的问题
我帮你梳理下代码里的几个关键问题,这些正是导致报错的原因:
1. 模块名称不匹配
你的顶层模块app依赖的是main模块,但main.js里定义的却是admin模块——Angular找不到main模块,直接触发了[$injector:modulerr]错误。先把模块名称统一:
// main.js 开头修改为 angular.module('main', ['ngRoute', 'ngSanitize', 'ngCsv'])
2. Provider结构逻辑错误
AngularJS的config阶段注入的是Provider实例,而不是$get方法返回的服务对象。你之前把when方法写在了$get返回的对象里,这意味着config阶段调用appRouteProvider.when时,这个方法根本不存在,才会出现when is not a function的错误。
正确的做法是把when方法直接定义在Provider的this上,同时修复path变量未定义的问题(需要注入$location获取当前路径):
// app.js 修正后代码 angular.module('app', ['ngRoute', 'ngSanitize' , 'main' ]) .provider('appRoute', ['$routeProvider', function($routeProvider) { // 通用权限校验逻辑,定义在Provider内部 var universalResolves = { authorize: ['$http', '$location', function($http, $location) { var path = $location.path(); return $http.get('/svc/authorize/view?urlPath=' + path) .then(function(response) { var data = response.data; if (data.result === 'NOT_AUTHORIZED') { throw "NOT_AUTHORIZED"; } console.log("finished authorized()"); return data; }); }] }; // 把when方法挂载到Provider实例上,config阶段就能直接调用 this.when = function(path, route) { // 合并自定义resolve和通用resolve route.resolve = angular.extend({}, route.resolve || {}, universalResolves); // 调用原生$routeProvider的when方法 $routeProvider.when(path, route); // 返回this支持链式调用 return this; }; // $get方法返回服务实例(如果运行时需要调用的话) this.$get = function() { console.log("Instantiating appRoute service"); return this; }; }]);
3. 语法错误:缺失闭合括号
你的main.js里,when方法的调用少了一个闭合的花括号,导致语法解析失败:
// main.js 修正后代码 angular.module('main', ['ngRoute', 'ngSanitize', 'ngCsv']) .config(['appRouteProvider', function(appRouteProvider) { appRouteProvider.when('/route', { templateUrl: 'pageTemplate.tmpl.html', controller: 'pageCtrl' }); // 这里补上缺失的闭合括号 }]);
额外优化建议
当抛出NOT_AUTHORIZED异常时,建议在全局路由错误事件中捕获并处理,比如跳转到登录页:
angular.module('app') .run(['$rootScope', function($rootScope) { $rootScope.$on('$routeChangeError', function(event, current, previous, rejection) { if (rejection === "NOT_AUTHORIZED") { console.log("用户未授权,跳转至登录页"); // 这里添加跳转逻辑,比如 $location.path('/login') } }); }]);
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

