[英]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.