Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/424.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使函数在angularjs中的两个或多个控制器之间可重用_Javascript_Angularjs_Angular Services - Fatal编程技术网

Javascript 如何使函数在angularjs中的两个或多个控制器之间可重用

Javascript 如何使函数在angularjs中的两个或多个控制器之间可重用,javascript,angularjs,angular-services,Javascript,Angularjs,Angular Services,我有一个问题,因为我对angularjs是新手。我搜索了很多,但无法理解这个概念。我有一个基本的概念,一个视图应该有一个控制器,但是我们可以有多个控制器。我在一个视图中有以下两个控制器,有一个函数,比如addComma函数,我必须在两个控制器中使用,但我想写一次,使它在所有控制器之间可重用,比如说在同一视图上的5,6个控制器。所以基本上,问题是如何使控制器中的函数在相同视图或其他视图的所有控制器之间处于全局状态,以便我可以在应用程序中的任何位置使用它。同位语如果这是一个愚蠢的问题,我很难理解an

我有一个问题,因为我对angularjs是新手。我搜索了很多,但无法理解这个概念。我有一个基本的概念,一个视图应该有一个控制器,但是我们可以有多个控制器。我在一个视图中有以下两个控制器,有一个函数,比如addComma函数,我必须在两个控制器中使用,但我想写一次,使它在所有控制器之间可重用,比如说在同一视图上的5,6个控制器。所以基本上,问题是如何使控制器中的函数在相同视图或其他视图的所有控制器之间处于全局状态,以便我可以在应用程序中的任何位置使用它。同位语如果这是一个愚蠢的问题,我很难理解angularjs的概念

 app.controller("GetChargesController", function ($scope, GetService, $rootScope) {
    $scope.Title = "Charges Details List";
    $rootScope.loading = true;
    // Calling Serivce Method here
    $scope.GetChargesDetails = GetService.GetAll("CommonApi", "GetChargesDetails").then(function (d) {
        $scope.ChargesDetails = d;
        $rootScope.loading = false;
    });
    // add comman function goes here
       $scope.addComma = function(x) {
        return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }

     });

    app.controller("GetPaymentsController", function ($scope, GetService, $rootScope) {
    $scope.Title = "Payments Details List";
    $rootScope.loading = true;
    // Calling Serivce Method here
    $scope.GetPaymentsDetails = GetService.GetAll("CommonApi", "GetPaymentsDetails").then(function (d) {
        $scope.PaymentsDetails = d;               
        $rootScope.loading = false;
    });
    // add comman function goes here
    $scope.addComma = function (x) {
        return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
       }

     });
下面是我编写的用于从数据库获取任何类型数据的通用服务(使用asp.NETWebAPI)。正如我所读到的,angular services可以保存数据,当我们在链接上来回移动时,我们不需要反复调用数据库,比如说,我在一个页面上有这3个链接。主页链接,付款费用链接,订单链接。因此,默认情况下主视图将打开。当我点击PaymentCharges链接时,呼叫将从数据库获取数据并呈现其视图,但当我点击Home链接上的back时,不应调用数据库获取主页数据,或者当我再次点击PaymentCharges链接上的forward时,不应调用数据库,但我在firebug上看到的是控制台选项它正在调用函数并转到数据库获取数据。我认为我们需要使用缓存来保存数据,以避免将调用发送到数据库

    app.factory("GetService", function ($http) {
    var thisService = {};

    // get all data from database
    thisService.GetAll = function (controllername, methodName) {
        var promise = $http({
            method: 'GET',
            url: '/api/'+controllername + '/' + methodName
        })
            .then(function (response) {
                return response.data;
            },
            function (response) {
                return response.data;
            });
        return promise;
    };
});

为什么不将数据存储在服务中

你可以做:

.then(function (resp) {
    thisService.controllerName.data = resp.data
}

然后,您可以使用
GetService.controllerName.data

创建一个utils服务并在其中添加
addComma
函数来引用代码中的变量。注入utils服务并在控制器中重用
addComma

app.factory('utils', function() {
  return {
    addComma: function() {}
  }
});

app.controller("GetChargesController", function ($scope, utils) {
  $scope.addComma = utils.addComma;
});

app.controller("GetPaymentsController", function ($scope, utils) {
  $scope.addComma = utils.addComma;
});

管理服务问题的几种方法:

通过将承诺存储在服务中,重新使用承诺:

 // create an object to store promises
var promises = {};
thisService.GetAll = function(controllername, methodName) {

    promises[controllername] = promises[controllername] || {};
    // if the particular promise doesn't already exist create it as a property of above object
    if (!promises[controllername][methodName]) {
      promises[controllername][methodName] = $http({...}).then(...;

    }
    // now return the specific stored promise
    return promises[controllername][methodName];
 };
或者存储数据并使用
$q
返回一个不同的承诺,当存储的数据已经存在时,该承诺将与存储的数据进行解析。确保为此方法注入
$q

var data = {};
thisService.GetAll = function(controllername, methodName) {

  data[controllername] = data[controllername] || {};

  if (data[controllername][methodName]) {
    // data exists for this controller and method, no need for new request
    return $q.resolve(data[controllername][methodName]);
  } else {
    return $http({...}).then(function(response) {
      // store the data for next use
      var newData = response.data;
      data[controllername][methodName] = newData;
      return newData;
    });    
  }   

};

相反,我建议你使用类似的东西,这可能会使它更通用一些。检查下面的代码

  • appResources工厂将包含需要公开的所有资源
  • indexServices工厂将包含与索引控制器对应的所有服务

    (function () {
    use strict';
    var commonServices = angular.module('commonServices', ['ngResource']);
    
    commonServices.factory('appResources', ['$resource',
       function ($resource) {
    
           var indexResource=$resource('/api/index/:id');
            return {
    
                   indexResource:indexResource
    
            }
    }]);
    
     commonServices.factory('indexService',['appResources',
     function (appResources){
    
        var getAllIndexes =function(sucesscallback){
    
           appResources.indexResource.query({}).$promise.then(
           //success
          function( value ){/*success events and Data is present in the 'value'*/
           sucesscallback(value);
           },
           //error
            function( error ){/*failure events*/}
           )
    
        }
    
       }
      ]);
    });
    
  • 控制器方法调用服务并获取$scope变量中的值,如

    (function () {
    'use strict';
     angular.module('saniehhaApp')
        .controller('indexController', indexController);
            indexController.$inject = ['$location', 'indexService'];
                function indexController($location, index,indexService) {
                /* jshint validthis:true */
                        indexService.getAllIndexes(function(sucesscallback){
                            $scope.value=sucesscallback;
                        })
                    //$locaton.qwets=....
                    }
    })();
    

  • 对于这种类型的函数,您可以创建一个自定义过滤器,我认为它适合您的问题。@qchap与角度无关filters@charlietfl我不同意你的看法。对于像这样的函数,
    $scope.addComma=function(x){return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g,“,”;}
    我认为过滤器是一个很好的选择,您可以只使用此函数的一个实现。但我同意这个命题只是问题的第一部分。@qchap ok…这里似乎有两个非常独立的问题。我的错。Aamer试图将问题集中在单个问题上。这种方法行不通,因为相同的
    GetAll
    也会进行许多不同的方法名称api端点调用,我认为您需要
    thisService[controllerName]data=resp.data
    then()
    也需要返回数据。这是作为psuedo代码使用的。OP当然必须调整它以适应他们的需要。总体概念仍然存在。将其存储在服务中。如果我们根据一些参数从数据库中获取数据,比如第一次发送日期参数以获取当前月份的数据,下一次要获取前3个月的数据,那么在这两种情况下,我们都必须向数据库发送调用,但如果两个请求的参数相同,则从数据库中获取数据服务我们是否可以在上述方法中添加一个参数检查,以检查参数是否有更改,然后转到数据库,否则返回存储在服务中的相同数据。我的意思是在服务或控制器中的何处添加此检查?可以有另一个存储参数的对象,并添加更多条件逻辑。只能用于存储数据,而不是promise概念。此外,您可能还希望合并数据,而不是过度写入数据。还有一些数据存储库,您可以调查所有这类检查都将投入使用。控制器只在视图和服务之间来回传递数据,并且在页面的整个生命周期中不会像服务感谢您一样持久。我已经将这个答案作为问题的第二部分,并将在我的代码中实现它。我还有更多问题,但你们投票否决了我,所以我无法在堆栈溢出上发布新问题-(谢谢你,盖拉我把这个答案作为我问题的第一部分。