Javascript 如何在控制器之间共享公共逻辑?

Javascript 如何在控制器之间共享公共逻辑?,javascript,angularjs,Javascript,Angularjs,我有两个页面和两个控制器在同一个数据集上执行搜索。其中一个有一个简单的表单来指定搜索条件。另一个允许用户选择地图上的数据(通过选择区域或单击地图上的要素) 然后,搜索结果显示在搜索控件下方的数据表上(在同一页上) 因此,控制器具有不同的搜索功能,但也有许多共同的行为,即显示网格、分页、重新加载、批量编辑网格中的数据等 因此,两个控制器中都有几个重复的功能,有时略有变化,有时完全相同 显示数据的页面部分也是一个共享模板,包含在两个搜索页面上的ng include 以下是一个例子: $scope.s

我有两个页面和两个控制器在同一个数据集上执行搜索。其中一个有一个简单的表单来指定搜索条件。另一个允许用户选择地图上的数据(通过选择区域或单击地图上的要素)

然后,搜索结果显示在搜索控件下方的数据表上(在同一页上)

因此,控制器具有不同的搜索功能,但也有许多共同的行为,即显示网格、分页、重新加载、批量编辑网格中的数据等

因此,两个控制器中都有几个重复的功能,有时略有变化,有时完全相同

显示数据的页面部分也是一个共享模板,包含在两个搜索页面上的
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);
        }
    });

};
它可以工作,但不是很优雅,因为它在全局范围内定义了一个函数,在任何角度模块之外


有没有一种独特的方法来实现这一点?或者至少更符合Angular架构?

我发现有些模式对我的用例很有用

两者都可以用于定义和继承控制器(缺少依赖关系管理和原型继承并不是最好的选择,但ES2015类在这种情况下非常有用)

或者可以利用角度相关性管理和:

有一些第三方解决方案,例如,为控制器提供自以为是的继承语法


$injector
$controller
也可用于访问父控制器并继承它,但由于引入了
controllerAs
语法,因此无需再乱搞
$scope

将公共函数放入
commonCtrl
的作用域并在子控制器中访问它们。角度子对象的
范围
继承自父对象的
范围

<div ng-controller='commonCtrl'>
    <div ng-controller='featureOneCtrl'></div>
</div>
<div ng-controller='commonCtrl'>
    <div ng-controller='featureTwoCtrl'></div>
</div>


听起来您需要一个基本控制器(以建立通用功能,并根据需要进行扩展)。对SO的搜索显示了几种变化,而谷歌则有更多的变化。(例如,只是许多示例中的一个,并将
$scope
传递给基,我觉得这就是您要寻找的)。似乎您需要将网格功能移动到Directive不要使用基控制器,因为您不会避免$scope继承,并且基控制器上的函数不会传递给具有隔离作用域的指令。公共功能应该是服务(逻辑)或指令(视图组件)的一部分。
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';
}]);
<div ng-controller='commonCtrl'>
    <div ng-controller='featureOneCtrl'></div>
</div>
<div ng-controller='commonCtrl'>
    <div ng-controller='featureTwoCtrl'></div>
</div>