Angular中的未知提供者:已检查一切无法理解错误的性质

时间:2016-03-28 15:20:02

标签: angularjs webpack

我正在为Angular应用程序创建一个登录系统,并且遇到了未知的提供程序错误。我检查了所有的东西5次,我没有看到什么是错的。

我正在使用Webpack作为构建系统。

错误文本如下:

angular.js:68 Uncaught Error: [$injector:modulerr] Failed to instantiate module Universe due to:
Error: [$injector:modulerr] Failed to instantiate module layout due to:
Error: [$injector:unpr] Unknown provider: Self

怀疑是4个javascript文件,构成3个模块:

  • app.js - 包含Universe模块
  • layout.module.js - 包含layout模块
  • auth.module.js - 包含auth模块
  • self.service.js - SelfResource
  • 中包含Self服务的auth工厂

资源工厂Self,表示有关已登录用户的信息,导致错误。

app.js

'use strict';

require("expose?$!expose?jQuery!jquery");
require("metisMenu/dist/metisMenu");
require("iCheck/icheck");
require("expose?_!lodash"); // was underscore

var angular = require("angular");
require("angular-animate");
require("angular-messages");
require("angular-resource");
require("angular-sanitize");
require("angular-cookies");
require("angular-ui-router");
require("bootstrap/dist/css/bootstrap.css");
require("font-awesome/css/font-awesome.css");
require("angular-bootstrap");

require("../assets/styles/style.scss");
require("../assets/fonts/pe-icon-7-stroke/css/pe-icon-7-stroke.css");
require("../assets/fonts/pe-icon-7-stroke/css/helper.css");

// Import all html files to put them in $templateCache
// If you need to use lazy loading, you will probably need
// to remove these two lines and explicitly require htmls
const templates = require.context(__dirname, true, /\.html$/);
templates.keys().forEach(templates);

var LayoutModule = require("layout/layout.module");
var HomeModule = require("home/home.module");
var AccountModule = require("account/account.module");
var WorkflowModule =  require("workflow/workflow/workflow.module");
var TaskModule = require("workflow/task/task.module");
var ToolModule = require("workflow/tool/tool.module");

var NavigationModule = require("../components/navigation/navigation.module");
var PanelModule = require("../components/panel/panel.module");
var UniverseDirectives = require("../components/directives");
var AuthModule = require("../components/auth/auth.module");

angular.module("Universe", [
    "ngAnimate",
    "ngMessages",
    "ngResource",
    "ngSanitize",
    "ngCookies",
    "ui.router",
    "ui.bootstrap",

    LayoutModule.name,
    HomeModule.name,
    AccountModule.name,
    WorkflowModule.name,
    TaskModule.name,
    ToolModule.name,

    NavigationModule.name,
    PanelModule.name,
    UniverseDirectives.name,
    AuthModule.name
])
.config(function($urlRouterProvider, $locationProvider, $stateProvider) {
    // $urlRouterProvider.otherwise('/');

    // $locationProvider.html5Mode(true);

    $stateProvider
      .state('test', {
        url: "/test",
        template: "This is a test"
      });
})
.run(function($rootScope, Auth) {
    $rootScope.Auth = Auth;
});

layout.js

import angular from "angular";

// @ngInject
function routes($stateProvider, Self) {
    $stateProvider.state("layout", {
        url: "",
        abstract: true,
        templateUrl: "/app/layout/layout.html",
        resolve: {
            self: function() {
                var self = Self({});
                return self;
            }
        }
    });
}

//export default 
module.exports = angular.module("layout", ["auth"]).config(routes);

auth.module.js

'use strict';

var AuthService = require("./auth.service");
var UserResource = require("./user.service");
var SelfResource = require("./self.service");
var AuthInterceptor = require("./interceptor.service");
var UtilModule = require("../util/util.module");

module.exports = angular.module('auth', [
  'ui.router',
  UtilModule.name
])
  .factory('Auth', AuthService)
  .factory('User', UserResource)
  .factory('Self', SelfResource)
  .factory('AuthInterceptor', AuthInterceptor)
  .config(function($httpProvider) {
    $httpProvider.interceptors.push('AuthInterceptor');
  })
  .run(function($rootScope, $state, Auth) {
      // This is router decorator, it redirects users, lacking priviledges, to login page

      // Redirect to login if route requires auth and the user is not logged in, or doesn't have required role
      $rootScope.$on('$stateChangeStart', function(event, next) {    
          if (!next.authenticate) {
            return;
          }

          if (typeof next.authenticate === 'string') {
              Auth.hasRole(next.authenticate, _.noop).then(has => {
                  if(has) {
                      return;
                  }

                  event.preventDefault();
                  return Auth.isLoggedIn(_.noop).then(is => {
                       $state.go(is ? 'main' : 'login');
                  });
              });
          }
          else {
              Auth.isLoggedIn(_.noop).then(is => {
                  if(is) {
                      return;
                  }

                  event.preventDefault();
                  $state.go('main');
              });
          }
      });    
  });    

self.service.js

'use strict';

// @ngInject
function SelfResource($resource) {
    return $resource('/api/self/',
        {},
        {
            get: {
                method: 'GET'
            }
        },
        {
            stripTrailingSlashed: false
        }
    );
}

module.exports = SelfResource;

所以,一切都应该有效:我在SelfResource中导入auth.module.js并将其声明为工厂。我还将auth模块(在auth.module.js中定义)声明为布局模块的依赖项。

Webpack编译没有错误,所有模块都存在于输出包中。为什么错误?

更新: 我在layout.module.js的开头添加了以下几行:

var authModule = require("../../components/auth/auth.module");
console.log(authModule);

给了我auth模块的内容:

Object {_invokeQueue: Array[4], _configBlocks: Array[1], _runBlocks: Array[1], requires: Array[2], name: "auth"}

_invokeQueue包含Self工厂。所以,我猜这是接收方面的一个奇怪问题。

1 个答案:

答案 0 :(得分:0)

你在这里有一个自定义吗?如果您的意思是SelfResource,请确保它已导入并正确注入。

import angular from "angular";

// @ngInject
function routes($stateProvider, Self) {
    $stateProvider.state("layout", {
        url: "",
        abstract: true,
        templateUrl: "/app/layout/layout.html",
        resolve: {
            self: function() {
                var self = Self({});
                return self;
            }
        }
    });
}

//export default 
module.exports = angular.module("layout", ["auth"]).config(routes);