简体   繁体   English

AngularJS:在控制器之间共享功能

[英]AngularJS: Sharing a function between controllers

I've read in other SO answers that code that doesn't manipulate the view should be accessed via services . 我在其他SO答案中读到,不应通过services访问不操纵视图的代码。 However, I have a function that I want to share over several Angular controllers, which accesses both $scope , $rootScope and $location : 但是,我有一个我想在多个Angular控制器上共享的函数,该函数可以同时访问$scope$rootScope$location

    $scope.selectBatch = function (id) {
        if (!id) {
            $scope.batchSelected = false;
            $rootScope.job = false;
            $scope.data = allData;
            $location.path('/', false);
        } else {
            $scope.batchSelected = id;
            $rootScope.job = {'BatchId': id};
            var arr = [];
            for (var i = 0; i < allData.length; i++) {

                if (String(allData[i].BatchId) === String(id)) {
                    arr.push(allData[i]);
                }
            }

            $scope.data = arr;
            $rootScope.go(id, 'batch');
        }
    };

Ideally, in each controller I'd like to do something like: 理想情况下,在每个控制器中,我想执行以下操作:

 $scope.selectBatch = services.selectBatch($scope, $rootscope, $location);

to load in this function from a service, although this feels "non-angular". 从服务中加载此功能,尽管感觉是“非角度的”。

What's the "Angular" / MVC way of injecting this sort of function into multiple controllers? 将这种功能注入多个控制器的“ Angular” / MVC方法是什么?

From the comments on this question it appears the correct answer is to do it like this: 从对这个问题的评论看来,正确的答案是这样做的:

1. Create a service that returns a function 1.创建一个返回函数的服务

angular.module('myApp.services', []).service('shared', ['$location', function ($location) {

   this.selectBatch = function($rootScope, $scope){
      return function(id){
         // Do stuff with $location, id, $rootScope and $scope here
      }
   }

}]);

2. Inject the service and associated functions into your controllers 2.将服务和相关功能注入控制器

.controller('myCtrl', ['shared', '$scope', '$rootScope'
    function (shared, $scope, $rootScope) {

        $scope.selectBatch = shared.selectBatch($rootScope, $scope);

}]);

You can then call this function using $scope.selectBatch(id) and it works as expected. 然后,您可以使用$scope.selectBatch(id)调用此函数,该函数将按预期工作。

Happy to consider other answers if there are "better" ways to achieve this. 如果有“更好”的方法来实现此目标,我们很乐意考虑其他答案。

Angular services are substitutable objects that are wired together using dependency injection (DI). Angular服务是使用依赖项注入(DI)连接在一起的可替换对象。 You can use services to organize and share code across your app. 您可以使用服务来组织和共享应用程序中的代码。

You can use services to organize and share code across your app 您可以使用服务来组织和共享应用中的代码

Be aware that sending $scope as parameter to a service is not a good idea. 请注意,将$ scope作为参数发送给服务不是一个好主意。 Instead you could send the parameters the function needs in order to process something. 相反,您可以发送函数需要处理的参数。 This way your service could be more reusable. 这样,您的服务可以更可重用。

Check this SO Question: Injecting $scope into an angular service function() 检查此SO问题: 将$ scope注入角度服务函数()

Ideally you could write a shared service like this: 理想情况下,您可以编写这样的共享服务:

app.factory('sharedService', ['$location', function($location)
{
    var sharedService = {};

    sharedService.selectBatch  = function(batchSelected, job, data, id)
    {
        //Do something with batchSelected, job, data, id parameters
    };

    return sharedService;
}]);

Then all your controllers could look like this 然后您所有的控制器可能看起来像这样

app.controller('myCtrl', ['sharedService', function(sharedService)
{

    $scope.batchSelected;
    $scope.job;
    $scope.data;
    $scope.id;

    $scope.selectBatch = sharedService.selectBatch($scope.batchSelected, $scope.job, $scope.data, $scope.id);
}]);

NOTE 注意

You don't have to send the $location parameter either, since you could inject it in your shared service. 您也不必发送$ location参数,因为您可以将其注入共享服务中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM