重構控制器的功能在不同的文件中聲明的服務
正如你所說的,重構函數的一個好方法是把它們放到不同的服務中。
按照angular Service docs:
角服務是單身對象或進行常見的web應用程序特定任務的功能。
下面是一個例子:
原始代碼
我們這裏有一個簡單的Hello World應用程序,帶有兩個功能的控制器:greet()
和getName()
。
app。JS
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.getName = function() {
return 'World';
}
$scope.greet = function (name) {
return 'Hello ' + name;
};
});
的index.html
...
<div id="container" ng-controller="MainCtrl">
<h1>{{greet(getName())}}</h1>
</div>
...
我們要測試我們的範圍總是有兩種功能,所以我們知道它的工作如預期,所以我們要編寫兩個簡單茉莉測試:
appSpec.js
describe('Testing a Hello World controller', function() {
var $scope = null;
var ctrl = null;
//you need to indicate your module in a test
beforeEach(module('plunker'));
beforeEach(inject(function($rootScope, $controller) {
$scope = $rootScope.$new();
ctrl = $controller('MainCtrl', {
$scope: $scope
});
}));
it('should say hallo to the World', function() {
expect($scope.getName()).toEqual('World');
});
it('shuld greet the correct person', function() {
expect($scope.greet('Jon Snow')).toEqual('Hello Jon Snow');
})
});
Check it out in plnkr
第1步:重構控制器功能整合到不同的功能
爲了開始我們的控制器去耦我們的功能,我們將做出內部app.js.兩個單獨的功能
app.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.getName = getName;
$scope.greet = greet;
});
function getName() {
return 'World';
}
function greet(name) {
return 'Hello ' + name;
}
現在我們檢查我們的測試輸出,我們看到,一切都可以正常使用。
Check out the plnkr for step 1
第2步:移動功能,以自己的服務
我們將定義一個名稱服務和GreetService,把我們的功能他們,然後定義服務作爲我們的控制器依賴。
app.js
var app = angular.module('plunker', []);
app.service('NameService', function() {
this.getName = function getName() {
return 'World';
};
});
app.service('GreetService', function() {
this.greet = function greet(name) {
return 'Hello ' + name;
}
});
app.controller('MainCtrl', ['$scope', 'NameService', 'GreetService', function($scope, NameService, GreetService) {
$scope.getName = NameService.getName;
$scope.greet = GreetService.greet;
}]);
我們確保我們的測試仍然是綠色的,所以我們可以移動到最後一步。
Have a look at step 2 in plunker
最後一步:把我們的服務在不同的文件
最後,我們將兩個文件,NameService.js和GreetService.js,把我們的服務在其中。
NameService.js
angular.module('plunker').service('NameService', function() {
this.getName = function getName() {
return 'World';
};
});
GreetService.js
angular.module('plunker').service('GreetService', function() {
this.greet = function greet(name) {
return 'Hello ' + name;
}
});
我們還需要確保新的腳本添加到我們的index.html
指數。html
...
<script src="NameService.js"></script>
<script src="GreetService.js"></script>
...
這就是我們的控制器看起來像現在一樣,整潔吧?
app.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', ['$scope', 'NameService', 'GreetService', function($scope, NameService, GreetService) {
$scope.getName = NameService.getName;
$scope.greet = GreetService.greet;
}]);
Plunker for the final step.
就是這樣!我們的測試仍然通過,所以我們知道一切都像魅力一樣。
你可以添加一個需要訪問範圍的效用函數的例子嗎?如果它真的是一個實用函數,應該可以重構它以不使用$ scope。否則它可能是一個指令的候選人。無論如何,很難說沒有一個例子。 – Narretz
Hi @Narretz,增加了一個例子。請不要爲我提供重構代碼或將其轉換爲指令的方式,我知道如何執行這些方法,這也不是我的問題。我想知道如何將函數移動到一個單獨的js文件。 tnx – Gidon
既然你不需要任何提示,那麼我只是說你使用控制器的方式不是角度「最佳實踐」。你可以在視圖中完全編寫你的例子,或者使用一個指令,甚至把函數放在一個服務中,然後把服務函數綁定到$ scope變量。不過,我不推薦它。 – Narretz