如何在控制器之间共享通用逻辑? [英] How to share common logic between controllers?

查看:83
本文介绍了如何在控制器之间共享通用逻辑?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have two pages and two controllers that perform searches on the same dataset. One has a simple form to specify search criteria. The other allows the user to select data on a map (by selecting an area or clicking on features on the map).

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

The result of the search is then displayed on a data table below the search controls (on the same page).

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

So, the controllers have different search features, but also share a lot of common behaviour, i.e. displaying the grid, paging, reloading, batch edition of data from the grid etc.

因此,有几个函数被重复,有时会有轻微变化,有时完全相同,在两个控制器中。

As a result, there are several functions that are repeated, sometimes with slight variations, sometimes exactly identical, in both controllers.

显示数据的页面部分也是一个共享模板,包含在 ng-include 在两个搜索页面上。

The part of the page that displays the data is also a shared template, included with ng-include on both search pages.

以下是一个示例:

$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

This function selects all the rows in the table. It is bound to the ng-click of a button on the page.

还有很多其他功能,比如这个,基本上从 $ scope 中读取一些状态,执行一些逻辑,并将新的东西放回 $ scope

There are many other functions like this, that basically read some state from the $scope, perform some logic, and place something new back to the $scope.

我想删除这些函数的重复,并在一个代码单元中重新组合常见行为。

I would like to remove the duplication of these functions and regroup the common behaviour in a single unit of code.

注意:我在这里分享的是行为,而不是数据。这些函数将执行相同的逻辑,但是在不同的范围内。

因为这些都是演示文稿/ UI的东西,需要放在 $ scope ,我不认为可以使用某项服务,因为 $ scope 是一个严格的控制器,无法注入进入服务。

Since these are really presentation / UI stuff, and need to be put on the $scope, I don't think a service could be used because the $scope is a strictly controller thing and cannot be injected into services.

我正在尝试在另一个文件中定义独立函数,并从两个控制器调用此函数:

I am experimenting with defining a standalone function, in a different file, and calling this function from both controller :

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模块。

It works but is not very elegant, since it defines a function in the global scope, outside of any Angular module.

是否有一种有角度的原生方式来实现这一目标?或者至少更符合Angular架构?

Is there a angular native way of achieving this ? Or at least more in line with the Angular architecture ?

推荐答案

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

There are some patterns which I found to be useful for my use cases.

中性JS代码可用于定义和继承您的控制器(缺乏依赖管理和原型继承不是最佳选择,但ES2015类是一个很好的帮助在这种情况下)。

Either neutral JS code can be used to define and inherit your controllers (the lack of dependency management and prototype inheritance don't make it the best option, but ES2015 classes are a great help in this case).

或者可以使用Angular依赖关系管理和存储服务中的常用方法和属性

Or the one can make use of Angular dependency management and store common methods and properties in a service:

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 ,为控制器提供自以为是的继承语法。

There are third-party solutions such as Classy that provide opinionated inheritance syntax for controllers.

$ injector $ controller 也可以用来访问父控制器并继承它,但是因为 controllerAs 语法被引入,不再需要弄乱 $ scope 了。

$injector or $controller can be also used to get access to parent controller and inherit it, but since controllerAs syntax was introduced, there's no need to mess around $scope anymore.

这篇关于如何在控制器之间共享通用逻辑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆