[英]How to share common logic between controllers?
我有兩個頁面和兩個控制器,它們對同一數據集執行搜索。 一種簡單的形式可以指定搜索條件。 另一個允許用戶在地圖上選擇數據(通過選擇區域或單擊地圖上的要素)。
搜索結果然后顯示在搜索控件下方的數據表上(在同一頁面上)。
因此,控制器具有不同的搜索功能,但也共享許多共同的行為,即顯示網格,分頁,重新加載,來自網格的數據批處理等。
結果,兩個控制器中的某些功能重復執行,有時會稍有變化,有時會完全相同。
頁面上顯示數據的部分也是共享模板,在兩個搜索頁面上都包含ng-include
。
這是一個例子:
$scope.selectAllRows = function(){
var selectedItems = $scope.searchState.selectedItems;
angular.forEach($scope.searchState.searchResult.rows, function(row){
// add only if not already selected
if(selectedItems.indexOf(row) < 0){
selectedItems.push(row);
}
});
};
此函數選擇表中的所有行。 它綁定到頁面上一個按鈕的ng-click
。
像這樣的許多其他函數,基本上是從$scope
讀取一些狀態,執行一些邏輯,然后將一些新東西放回$scope
。
我想刪除這些功能的重復項,並在單個代碼單元中重新組合常見行為。
注意:我要在此處分享的是行為,而不是數據。 這些功能將執行相同的邏輯,但作用域不同。
由於這些實際上是表示/ UI的東西,需要放在$scope
,因此我認為不能使用服務,因為$scope
是嚴格的控制器,不能注入到服務中。
我正在嘗試在另一個文件中定義一個獨立函數,然后從兩個控制器中調用此函數:
myapp.defineCommonControllerBehaviour = function($scope, someOtherService){
$scope.selectAlRows = function(){....}
$scope.someOtherCommonTask = function(){
someOtherService.doTheTask();
}
//etc...
};
//controller 1
myapp.defineCommonBehaviour($scope, someOtherService);
//controller 2
myapp.defineCommonBehaviour($scope, someOtherService);
它可以工作,但不是很優雅,因為它在任何Angular模塊之外的全局范圍內定義了一個函數。
有沒有實現此目標的有角度的本地方法? 還是至少更符合Angular架構?
我發現有些模式對我的用例有用。
兩種中性的JS代碼都可以用來定義和繼承您的控制器(缺少依賴管理和原型繼承並不是使其成為最佳選擇,但是ES2015類在這種情況下有很大幫助)。
或者,可以利用Angular依賴管理並在服務中存儲常用方法和屬性 :
myApp.service('baseCtrl', function () {
this.name = 'base';
this.getName = function() {
return this.name;
};
});
myApp.controller('MainController', ['baseCtrl', function (baseCtrl) {
angular.extend(this, baseCtrl);
this.name = 'main';
}]);
有第三方解決方案(例如Classy)為控制器提供了明確的繼承語法。
$injector
或$controller
也可以用來訪問父控制器並繼承它,但是由於引入了controllerAs
語法,因此不再需要在$scope
周圍亂七八糟。
將通用函數放入commonCtrl
的范圍,並在子控制器中訪問它們。 有角兒童的scope
繼承自父級的scope
。
<div ng-controller='commonCtrl'>
<div ng-controller='featureOneCtrl'></div>
</div>
<div ng-controller='commonCtrl'>
<div ng-controller='featureTwoCtrl'></div>
</div>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.