AngularJS - 错误:未知提供者:searchResultsProvider

use*_*187 1 angularjs karma-runner

编辑:我已经设法让我的单元测试运行 - 我将包含服务的代码移动到另一个文件和一个不同的模块,使这个新模块成为fooBar模块的要求,然后在调用每个"it"块之前,引入代码beforeEach(module(<new_service_module_name)).但是,我的应用程序仍然无法运行.控制台也没有错误.这是唯一仍然存在的问题 - 当我使用全局范围进行控制器定义时,应用程序可以工作,但是当我使用angular.module.controller时 - 它没有.

我有一个app.js包含以下内容的文件:

'use strict';

var app = angular.module('fooBar', []);

app.config(['$routeProvider', function($routeProvider) {
  $routeProvider.
  when('/', {
    templateUrl: 'partials/form-view.html',
    controller: FormViewCtrl
  }).
  when('/resultDisplay', {
    templateUrl: 'partials/table-view.html',
    controller: TableViewCtrl
  }).
  otherwise({redirectTo: '/'});
}]);

app.service('searchResults', function() {
  var results = {};

  return {
    getResults: function() {
      return results;
    },
    setResults: function(resultData) {
      results = resultData;
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

我有另一个controllers.js包含以下内容的文件:

'use strict';

var app = angular.module('fooBar', []);

app.controller('FormViewCtrl', ['$scope', '$location', '$http', 'searchResults', 
    function ($scope, $location, $http, searchResults) {
        //Controller code
}]);
Run Code Online (Sandbox Code Playgroud)

searchResults是我创建的一个服务,只有getter和setter方法.上面的控制器使用setter方法,因此服务被注入其中.

结果,我的应用程序只是没有运行!如果我将控制器代码更改为全局,如下所示:

function ($scope, $location, $http, searchResults) {
    //Controller code
}
Run Code Online (Sandbox Code Playgroud)

然后应用程序工作!

此外,如果我使用全局范围,则以下单元测试用例有效:

'use strict';

/*jasmine specs for controllers go here*/
describe('Foo Bar', function() {

    describe('FormViewCtrl', function() {
        var scope, ctrl;

        beforeEach(module('fooBar'));

        beforeEach(inject(function($rootScope, $controller) {
            scope = $rootScope.$new();
            ctrl = $controller('FormViewCtrl', {$scope: scope});
        }));
        }
        //"it" blocks
}
Run Code Online (Sandbox Code Playgroud)

如果我恢复到模块范围,我会收到错误 -
Error: Unknown provider: searchResultsProvider <- searchResults

因此,通过使用全局范围我的应用程序和单元测试运行,但通过使用app.controller,它们似乎打破了.

我注意到的另一点是,如果我包含控制器代码app.js而不是controllers.js,那么应用程序和单元测试将再次开始工作.但是我不能将它们包含在同一个文件中 - 如何在角度范围内运行它而不破坏应用程序和单元测试?

Sco*_*lvi 9

你不需要走那条路.您可以使用模块化方法,但问题在于您的第二个参数.

在你的app.js中你有这个:

var app = angular.module('fooBar', []);
Run Code Online (Sandbox Code Playgroud)

然后在你的控制器中,你有这个:

var app = angular.module('fooBar', []);
Run Code Online (Sandbox Code Playgroud)

你在那里做的是定义模块两次.如果您只是尝试连接到app模块,则无法传入第二个参数(空数组:) [],因为这会创建一个全新的模块,覆盖第一个参数.

我是这样做的(基于这篇文章来构建大型AngularJS应用程序.

app.js:

angular.module('fooBar',['fooBar.controllers', 'fooBar.services']);
angular.module('fooBar.controllers',[]);
angular.module('fooBar.services', []);
...etc
Run Code Online (Sandbox Code Playgroud)

controllers.js

angular.module('foobar.controllers') // notice the lack of second parameter
    .controller('FormViewCtrl', function($scope) {
        //controller stuffs
    });
Run Code Online (Sandbox Code Playgroud)

或者,对于非常大的项目,建议不要按类型(指令,过滤器,服务,控制器)对顶级模块进行分组,而是按功能(包括所有部分模块)对其进行分组......其原因是完全模块化 - 您可以创建一个新模块,使用相同的名称,新的部分和代码,将其作为替代品放入您的项目中,并且它将简单地工作),例如

app.js

angular.module('fooBar',['fooBar.formView', 'fooBar.otherView']);
angular.module('fooBar.formView',[]);
angular.module('fooBar.otherView', []);
...etc
Run Code Online (Sandbox Code Playgroud)

然后在formView挂在Web根目录下的文件夹中,您可以根据类型分离出您的文件,例如:

formView.directives
formView.controllers
formView.services
formView.filters

And then, in each of those files, you open with: 

angular.module('formView')
    .controller('formViewCtrl', function($scope) {

angular.module('formView')
    .factory('Service', function() {

etc etc
Run Code Online (Sandbox Code Playgroud)

HTH