初學者的Controller
在我們當接觸NG后,如需要通過訪問遠程的API獲取一系列的數據進行顯示,通常我的Controller代碼會寫成下面的樣子:
angular.module('demo') .controller('myCtrl',['$scope','$http', function($scope,$http){ $http.get("xxx") .success(function(response) { $scope.data = response.data; }); }]);
這樣的在功能上是沒有問題的,但是會導致Controller除了負擔了與View層的$scope變量的初始化和防范定義還需要額外注入http進行遠程的數據調用。
如當調用API的代碼是會大量被引用、或是API變更時候會導致大面的修改Controller代碼。
分離Service
Service層和Controller層的分工
我們將原來全部集中在Controller中代碼拆分成兩個層面:
- service層:主要負責數據交互和數據處理、處理一些業務領域上的邏輯;
- controller層:主要負責初始化$scope的變量用於傳遞給view層,並且處理一些頁面交互產生的邏輯;
什么情況下需要編寫Service
當一個功能是設計遠程API調用、數據集、業務領悟復雜邏輯、將會大量重復的運算方法時就可以考慮將代碼以service形式注入controller層。
編寫Service
將原先的代碼從Controller中抽離處理,代碼如下:
angular.module('demo') .service('myService',['$http',function($http){ return { getData:function(){ return $http.get("xxx"); } } }]);
則Controller的代碼將會被注入myService用於獲取相關的數據
angular.module('demo') .controller('myCtrl',['$scope','myService', function($scope,$http,myService){ myService.getData().success(function(response) { $scope.data = response.data; }); }]);
基本上這樣的代碼看上去很不錯了,但是我們依舊在Controller層處理了通訊時的回調函數success,這樣controller雖然直接依賴http了,但是還是間接的需要處理http。
在Service層處理通訊回調,將業務回調傳遞給Controller層
這里需要引入deffered將http的通訊級的回調在Service層處理完后,再重新交由controller去處理其他的問題。
angular.module('demo') .service('myService',['$http','$q',function($http,$q){ return { getData:function(){ var deferred = $q.defer(); var promise = $http.get("xxx"); promise.then( // 通訊成功的處理 function(answer){ //在這里可以對返回的數據集做一定的處理,再交由controller進行處理 answer.status = true; deferred.resolve(answer); }, // 通訊失敗的處理 function(error){ // 可以先對失敗的數據集做處理,再交由controller進行處理 error.status = false; deferred.reject(error); }); //返回promise對象,交由controller繼續處理成功、失敗的業務回調 return deferred.promise; } } }]);
相應的在controller中我們也可以進行相關事件的處理,修改代碼如下
angular.module('demo') .controller('myCtrl',['$scope','myService', function($scope,myService){ myService.getData().then( function(answer){ $scope.data = answer; }, function(error){ $scope.error = error; } ); }]);
這樣controller和servic的職業分離,並且controller完全不依賴http而只是依賴service傳遞的事件和數據。再編寫測試代碼時,其邏輯也會變得簡單。並且多個controller可以調用一個service中相同的方法,而不是通過曾經那種復制的方法來解決。
分層編寫代碼的最終目的無非就是
- 增加代碼的復用性;
- 代碼責任簡單,不會又做保姆又做司機,可讀性強容易理解;
- 編寫測試代碼的時候容易編寫;
- 減少對一些框架和環境插件的依賴;
- 修改邏輯時最小幅度的修改代碼
- 數據層發生變更修改Service,UI層有變化則修改Controller。不用擔心改controller把service也一起帶到溝里的情況發生。
最后的最后
AngularJS在許多框架的設計方面與Java的Spring非常類似,如你有一定的Java基礎應該很能理解為贏編寫出分層的代碼。
文/AkiraPan(簡書作者)
原文鏈接:http://www.jianshu.com/p/1e1aaf0fd30a
著作權歸作者所有,轉載請聯系作者獲得授權,並標注“簡書作者”。
原文鏈接:http://www.jianshu.com/p/1e1aaf0fd30a
著作權歸作者所有,轉載請聯系作者獲得授權,並標注“簡書作者”。