【问题标题】:Angular Initialization errors in app.jsapp.js 中的 Angular 初始化错误
【发布时间】:2016-10-21 18:09:25
【问题描述】:

所以我试图加入 Angular 的潮流,我的任务是构建一个 SPA,为此我选择了带有 ASP.Net MVC Web API 的 AngularJS(我是一名 .Net 开发人员)。作为强类型语言的粉丝,我在整个职业生涯中尽可能避免使用 javascript,但近年来 AngularJS 和其他库和插件等框架已经让我无法忽视。所以我在这里,请求一些指导。

我已经观看了教程,完成了示例代码项目并在 PluralSight 上进行了一些学习,并且至少从基础的角度来看,我的工作正常。我在 MVVM 和 MVC 方面有丰富的背景,所以 SOC 对我来说是一件大事。我喜欢 Angular 提供的 MVC 类型的结构,这也是我最初选择这条路线的主要原因。

现在让我谈谈我的问题。为了简单起见,我正在我的母版页 (_Layout.cshtml) 中初始化我的模块(当前),这是我在调整和试验时所做的。

<script>
    angular.module('xcmApp', ['ngRoute', 'ngResource'])
        .config(function ($routeProvider) {
            $routeProvider
            .when('/',
            {
                controller: 'companiesController',
                templateUrl: 'views/companylist.html'
            })
            .when('/Reports',
            {
                controller: 'reportsController',
                templateUrl: 'views/reportlist.html'
            })
            .otherwise({ redirectTo: '/' })
        })
        .factory('companiesFactory', ['$resource',
            function ($resource) {
                return $resource('/api/companies', {}, {
                    query: { method: 'GET', params: {}, isArray: true }
                });
            }
        ])
        .controller('companiesController', function ($scope, companiesFactory) {
            $scope.Companies = companiesFactory.query();
    });

</script>

但是现在我已经准备好继续深入的概念,我想将我的脚本分解成相应的文件。即,app.js 和相关的控制器/工厂/服务等。但是,当我将该脚本移动到 app.js 并在 _Layout.cshtml 中引用它时,它会出错:

<script src="~/app.js"></script>

错误:[$injector:unpr] 未知提供者:a

现在,当我什至无法让 app.js 正常工作时,继续闯入控制器文件等是没有意义的,所以我被卡住了。我知道这里有一些出色的 AngularJS 开发人员可能在读到这里之前就知道我缺少什么,我非常感谢您的帮助。

任何能突出我的疏忽的人今天都会成为我的超级巨星。提前致谢!

编辑:

这是我的堆栈跟踪:

    0x800a139e - JavaScript runtime error: [$injector:modulerr] Failed to instantiate module xcmApp due to:
Error: [$injector:unpr] Unknown provider: a
http://errors.angularjs.org/1.3.15/$injector/unpr?p0=a
   at Anonymous function (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:4015:13)
   at getService (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:4162:11)
   at invoke (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:4191:9)
   at runInvokeQueue (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:4109:11)
   at Anonymous function (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:4118:11)
   at forEach (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:323:11)
   at loadModules (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:4099:5)
   at createInjector (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:4025:3)
   at doBootstrap (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:1452:5)
   at bootstrap (http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js:1473:5)
http://errors.angularjs.org/1.3.15/$injector/modulerr?p0=xcmApp&p1=Error%3A%20%5B%24injector%3Aunpr%5D%20Unknown%20provider%3A%20a%0Ahttp%3A%2F%2Ferrors.angularjs.org%2F1.3.15%2F%24injector%2Funpr%3Fp0%3Da%0A%20%20%20at%20Anonymous%20function%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A4015%3A13)%0A%20%20%20at%20getService%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A4162%3A11)%0A%20%20%20at%20invoke%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A4191%3A9)%0A%20%20%20at%20runInvokeQueue%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A4109%3A11)%0A%20%20%20at%20Anonymous%20function%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A4118%3A11)%0A%20%20%20at%20forEach%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A323%3A11)%0A%20%20%20at%20loadModules%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A4099%3A5)%0A%20%20%20at%20createInjector%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A4025%3A3)%0A%20%20%20at%20doBootstrap%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A1452%3A5)%0A%20%20%20at%20bootstrap%20(http%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.15%2Fangular.js%3A1473%3A5)

提醒:

我的问题不是它不起作用,它确实起作用。当我将 Javascript 从 HTML 页面中取出并将其放入引用的 app.js 文件中时,它就会停止工作。

【问题讨论】:

  • 您使用的是缩小版的 Angular 吗?如果您使用 angular.js 的未缩小版本,您会得到一个更详细的错误,可以帮助您。
  • 我正在使用未缩小的 Angular://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js

标签: angularjs asp.net-mvc asp.net-web-api single-page-application


【解决方案1】:

返回文档。您正在使用一种错误的方式来定义您的应用程序。试试:

var MyApp = angular.module( 'MyApp', ['ngRoute' , 'ngSanitize']) ;

然后使用MyApp添加控制器、过滤器等

编辑:

顺便说一句,在单独的文件中为 SPA 编写 Javascript 是一个好习惯(我猜你不是在写一个小项目)。

【讨论】:

  • 感谢您的回复,但即使按照您的建议定义模块,也会导致我上面提到的错误:
【解决方案2】:

您的控制器定义中似乎缺少一些与依赖注入相关的声明部分。

在发布具体代码和修复之前,我想提一下一个有用的依赖注入问题的故障排除工具。 Angular 有一个内置指令ng-strict-di。该指令与ng-app 配套使用。来自ng-app documentation

如果该属性存在于 app 元素上,则注入器将以“strict-di”模式创建。这意味着应用程序将无法调用不使用显式函数注释(因此不适合缩小)的函数,如the Dependency Injection guide 中所述,有用的调试信息将有助于追踪这些错误的根源。

现在,到您帖子中的代码:

您的控制器未使用显式函数注释。在显式函数注释中,您传递依赖项的字符串数组,然后是函数。这确保了即使缩小要重命名函数参数,Angular 仍然可以识别要提供给函数的依赖项。您在部分代码中使用了显式注释,但控制器定义中缺少它。

这很容易识别,使用Error: [$injector:unpr] Unknown provider: a,即使您从未定义过名为a 的提供程序。 ng-strict-di 会标记这个控制器代码。

这是当前代码,以及建议的修复。

代替:

.controller('companiesController', function ($scope, companiesFactory) {

试试:

.controller('companiesController', ['$scope', 'companiesFactory', function ($scope, companiesFactory) {

【讨论】:

  • 我按照建议更改了控制器声明,当我将脚本移出我的 HTML 页面并进入引用的 app.js 时,结果是相同的。我能够获得整个堆栈跟踪,这对我来说不是很有价值,因为我有限的 Angular(当然是 JS)暴露,但也许它对你意味着什么:(太长的评论,我将编辑 OP)跨度>
  • 您也没有在.config 块中使用此表单;您可以尝试更改它,并检查ng-strict-di 是否为您提供任何新信息?
【解决方案3】:

我没有 ASP.net 背景,但我认为回答您的 Angular 问题并不重要。

首先像这样声明你的模块:

angular.module('myModule', []);

然后像这样获取他们的 oder 文件:

angular.module('myModule').controller/foactory/....

所以你的代码应该是这样的:

//xcmApp.module.js
angular.module('xcmApp', ['ngRoute', 'ngResource']);

//xcmApp.config.js
angular.module('xcmApp').config(function ($routeProvider) {
    $routeProvider
        .when('/',
            {
                controller: 'companiesController',
                templateUrl: 'views/companylist.html'
            })
        .when('/Reports',
            {
                controller: 'reportsController',
                templateUrl: 'views/reportlist.html'
            })
        .otherwise({redirectTo: '/'})
});

//xcmApp.factory.js
angular.module('xcmApp').factory('companiesFactory', ['$resource',
    function ($resource) {
        return $resource('/api/companies', {}, {
            query: {method: 'GET', params: {}, isArray: true}
        });
    }
]);

//xcmApp.controller.js
angular.module('xcmApp').controller('companiesController', function ($scope, companiesFactory) {
    $scope.Companies = companiesFactory.query();
});

编辑:

关于错误,请记住您的依赖项必须是正确的顺序。 所以你的 index.html(假设你还没有使用脚本加载器)应该是这样的:

<script src="/*path to angular*/"></script>
<script src="/*path to ngRoute*/"></script>
<script src="/*path to ngResource*/"></script>

<script src="/*path to xcmApp.module.js*/"></script> //setting your app module must come first
<script src="/*path to xcmApp.config.js*/"></script>
<script src="/*path to xcmApp.factory.js*/"></script> //must come before the controller in your case
<script src="/*path to xcmApp.controller.js*/"></script>

【讨论】:

  • 我正在为 Angular 库使用 CDN,因此我的 HTML 主机页面的头部有以下引用:。至于其他 JS 引用,我使用 Grunt 来组合和缩小我的脚本,因此所有源脚本最终都会在 app.js 输出文件中缩小。我相当肯定这不是我的错误的原因。
  • 为什么我的这个答案被否决了?我在 Stack Overflow 上学习和分享知识。所以如果这个答案是错误的,请告诉我为什么。
猜你喜欢
  • 2022-08-23
  • 1970-01-01
  • 2014-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-28
  • 1970-01-01
相关资源
最近更新 更多