自定义路由提供程序不是功能时

时间:2019-05-30 18:54:53

标签: javascript angularjs

这是从今天早上开始的问题的更新版本。

我有两个独立的模块,“管理员”和“授权”。在提供者授权块中,我扩展$routeProvider以便将相同的路由附加到所有路由定义。

首先,这是admin.js:

angular.module('authorization', [])
    .provider('$appRoute', function () {
        this.$get = function($routeProvider) {
            var universalResolves = {authorize: function($authorization) {
                    return $authorization.authorize();
                }};

            var extendedRouter = angular.extend({}, $routeProvider, {
                when: function(path, route) {
                    route.resolve = (route.resolve) ? route.resolve : {};
                    angular.extend(route.resolve, universalResolves);
                    $routeProvider.when(path, route);
                    return this;
                }
            });

            return new extendedRouter();
        }
    })
    .factory('$authorization', ['$http', '$location', function($http, $location) {

        var $authorization = {};

        $authorization.authorize = function() {

            var path = $location.path();

            return promise = $http.get('/svc/authorize/view?urlPath=' + path).then(function(response) {
                var data = response.data;
                if (response.data.result === 'NOT_AUTHORIZED') {
                    throw "NOT_AUTHORIZED";
                }

                return data;
            });

        };

        return $authorization;
    }]);

接下来,我的管理模块:

angular.module('admin', ['ngRoute', 'ngSanitize', 'ngCsv'
        , 'authorization'
    ])

    .controller('mainCtrl', function() {

    })
    .config(['$routeProvider', '$appRouteProvider', function($routeProvider, $appRouteProvider) {

        // old definition that needs to be changed to $appRouteProvider
        $routeProvider.when('/login', {
            templateUrl: '/login/auth.html',
            controller: 'loginCtrl'
        });

        $appRouteProvider.when('/page', {
            templateUrl: 'page.tmpl.html',
            controller: 'pageCtrl'
        });

不幸的是,我收到以下错误:

Error: [$injector:modulerr] Failed to instantiate module app due to:
$appRouteProvider.when is not a function
@https://localhost:8443/admin.js:87:9
invoke@https://localhost:8443/js/angular/angular.js:4718:16
runInvokeQueue@https://localhost:8443/js/angular/angular.js:4611:11
loadModules/<@https://localhost:8443/js/angular/angular.js:4620:11
forEach@https://localhost:8443/js/angular/angular.js:321:11
loadModules@https://localhost:8443/js/angular/angular.js:4601:5
loadModules/<@https://localhost:8443/js/angular/angular.js:4618:40
forEach@https://localhost:8443/js/angular/angular.js:321:11
loadModules@https://localhost:8443/js/angular/angular.js:4601:5
createInjector@https://localhost:8443/js/angular/angular.js:4523:19
doBootstrap@https://localhost:8443/js/angular/angular.js:1758:20
bootstrap@https://localhost:8443/js/angular/angular.js:1779:12
angularInit@https://localhost:8443/js/angular/angular.js:1664:5
@https://localhost:8443/js/angular/angular.js:31763:5
j@https://localhost:8443/js/jquery/jquery.min.js:2:29566
g/</k<@https://localhost:8443/js/jquery/jquery.min.js:2:29882

因此,它看到$ appRouteProvider,但只能看到this.$get()方法。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:3)

仅就错误而言,$appRoute提供者并未对其自身(除$get之外)公开任何方法。因此,它是一个空的api配置提供程序对象。

使用基本提供者配方时,$get方法用于提供生成服务的功能,而this中的provider用于将额外的配置功能绑定到将数据放入$get函数以后可以使用。

来自Angular provider docs

myApp.provider('unicornLauncher', function UnicornLauncherProvider() {
  var useTinfoilShielding = false;

  // provider config api method.
  this.useTinfoilShielding = function(value) {
    useTinfoilShielding = !!value;
  };

  this.$get = ["apiToken", function unicornLauncherFactory(apiToken) {

    // let's assume that the UnicornLauncher constructor was also changed to
    // accept and use the useTinfoilShielding argument
    return new UnicornLauncher(apiToken, useTinfoilShielding);
  }];
});

如果要在提供程序上添加其他方法,则可以使用this.when = ...Angular.extends(this, ....)例如。

答案 1 :(得分:0)

我最终选择了比扩展路由提供者更简单的解决方案。

在我的“顶层”模块中,我使用以下代码修改了所有路由:

angular.module('app'[])
    .run(function($route) {
        var keys = Object.keys($route.routes);
        keys.forEach(function(key) {
            var modifiedRoute = $route.routes[key];

            // if there's already a resolve function defined, don't overwrite it, just add a new one
            modifiedRoute.resolve = key.resolve?key.resolve:{};
            modifiedRoute.resolve.authorize = function($authorization) {
                return $authorization.authorize();
            }

            $route[key] = modifiedRoute;
        });
     });

之所以可行,是因为路由已在其他模块.config()块中定义,而其他模块在run()块之前执行。有点难看,但是可以用。