2013-04-14 103 views
1

編輯:我設法讓我的單元測試運行 - 我將包含服務的代碼移動到不同的文件和不同的模塊,使這個新模塊成爲fooBar模塊的一個要求,然後在每個「it」塊被調用之前,引入代碼beforeEach(module(<new_service_module_name))。但是,我的應用程序仍然無法運行。控制檯中也沒有錯誤。這是唯一的問題 - 當我使用全局作用域控制器定義時,應用程序可以工作,但是當我使用angular.module.controller時 - 它不會。AngularJS - 錯誤:未知提供者:searchResultsProvider

我有一個包含以下內容的文件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; 
    } 
    }; 
}); 

我有一個包含以下另一個文件controllers.js

'use strict'; 

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

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

searchResults是我創建的只是具有吸氣服務和setter方法。上面的控制器使用setter方法,因此服務被注入到它中。

因此,我的應用程序不運行! 如果我改變控制器代碼是全球性的這樣:

function ($scope, $location, $http, searchResults) { 
    //Controller code 
} 

然後應用程序的工作!

而且,如果我用的是全球範圍內,那麼下面的單元測試用例的工作原理:

'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 
} 

如果我恢復到模塊的範圍,我得到的錯誤 -
Error: Unknown provider: searchResultsProvider <- searchResults

因此通過使用全局範圍我的應用程序和單元測試運行,但通過使用app.controller,他們似乎打破。

我注意到的另一點是,如果我將控制器代碼包含在app.js而不是controllers.js中,那麼應用程序和單元測試將再次開始工作。但是我不能將它們包含在同一個文件中 - 我如何在不中斷應用程序和單元測試的情況下在角度範圍內運行它?

+0

而不是編輯你應該創建一個新的答案,並標記爲正確的! – Soviut

回答

2

好的 - 我終於明白了。基本上,如果你想使用該模塊範圍,而不是全球範圍內,那麼我們需要做到以下幾點(如果你有一個像app.jscontrollers.js的設置):

  1. 在app.js,定義模塊範圍:

    var myApp = angular.module(<module_name>, [<dependencies>]);

  2. 在controllers.js,不要再定義對myApp - 而不是直接使用它像:

    myApp.controller(..);

這樣做 - 我的應用程序和單元測試現在工作正常!

9

你不需要去那條路線。您可以使用模塊化方法,但問題在於您的第二個參數。

在你app.js你有這樣的:

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

然後在你的控制器,你有這樣的:

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

你在做什麼有兩次定義模塊。如果您只是嘗試附加到應用程序模塊,則無法傳入第二個參數(空數組:[]),因爲這會創建一個全新的模塊,從而覆蓋第一個模塊。

這裏是我如何做到這一點(成爲構建大AngularJS應用基於this article

app.js:

angular.module('fooBar',['fooBar.controllers', 'fooBar.services']); 
angular.module('fooBar.controllers',[]); 
angular.module('fooBar.services', []); 
...etc 

controllers.js

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

或者,對於非常大項目中,建議不要按類型(指令,過濾器,服務,控制器)對頂級模塊進行分組,而要使用功能(包括所有部分...)原因在於總體模塊化 - 您可以創建一個新模塊,使用相同名稱,新代碼&,將其放入您的項目中作爲替代品,並且它將簡單地工作)。

app.js

angular.module('fooBar',['fooBar.formView', 'fooBar.otherView']); 
angular.module('fooBar.formView',[]); 
angular.module('fooBar.otherView', []); 
...etc 

,然後在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 

HTH

+1

Thankyou ..這解決了我的問題。我在文檔中找不到兩次無法定義應用程序依賴關係的文檔。正如你所說,它正在重新定義我的主要模塊。改變,解決了這個錯誤對我來說。 –

1

最好的做法是隻有一個全局變量,您的應用程序並附加所有需要的模塊功能,以便您的應用程序以

var app = angular.module('app',[ /* Dependencies */ ]); 

在您的controller.js中,您已經將其重新啓動到一個新變量中,失去了之前連接的所有服務和配置,只啓動一次應用變量,再次重做會導致您失去服務你重視它

,然後添加一個服務(工廠版)

app.factory('NewLogic',[ /* Dependencies */ , function( /* Dependencies */) { 
return { 
function1: function(){ 
    /* function1 code */ 

    } 
    } 
}]); 

的控制器

app.controller('NewController',[ '$scope' /* Dependencies */ , function($scope /* Dependencies */) { 
$scope.function1 = function(){ 
    /* function1 code */ 
    }; 
    } 
}]); 

,並且對於指令和配置,您也可以創建您的一個應用程序模塊,並將所有需要的控制器,指令和服務附加到它上面,但都包含在父應用程序模塊變量中。

我看了一次又一次,對JavaScript的它是隻曾經有一個全局變量,因此angularjs架構最佳實踐真正填補了這個要求很好,

哦,對依賴陣列封裝實際上沒有必要的,但將創建一個混亂的全局變量和完全打破應用程序,如果你想縮小你的JS這麼好的主意,始終堅持最佳實踐,而不是做解決辦法讓事情工作

0

在我的情況,我已經定義一個新的提供商,說,xyz

angular.module('test') 
.provider('xyz', function() { 
    .... 
}); 

當你配置上述提供者時,你已經注入'提供者'字符串。

例:

angular.module('App', ['test']) 
.config(function (xyzProvider) { 
    // do something with xyzProvider.... 
}); 

如果沒有「提供者」串注入上述供應商,你會得到OP的類似錯誤。

相關問題