Javascript 如何使函数在angularjs中的两个或多个控制器之间可重用
我有一个问题,因为我对angularjs是新手。我搜索了很多,但无法理解这个概念。我有一个基本的概念,一个视图应该有一个控制器,但是我们可以有多个控制器。我在一个视图中有以下两个控制器,有一个函数,比如addComma函数,我必须在两个控制器中使用,但我想写一次,使它在所有控制器之间可重用,比如说在同一视图上的5,6个控制器。所以基本上,问题是如何使控制器中的函数在相同视图或其他视图的所有控制器之间处于全局状态,以便我可以在应用程序中的任何位置使用它。同位语如果这是一个愚蠢的问题,我很难理解angularjs的概念Javascript 如何使函数在angularjs中的两个或多个控制器之间可重用,javascript,angularjs,angular-services,Javascript,Angularjs,Angular Services,我有一个问题,因为我对angularjs是新手。我搜索了很多,但无法理解这个概念。我有一个基本的概念,一个视图应该有一个控制器,但是我们可以有多个控制器。我在一个视图中有以下两个控制器,有一个函数,比如addComma函数,我必须在两个控制器中使用,但我想写一次,使它在所有控制器之间可重用,比如说在同一视图上的5,6个控制器。所以基本上,问题是如何使控制器中的函数在相同视图或其他视图的所有控制器之间处于全局状态,以便我可以在应用程序中的任何位置使用它。同位语如果这是一个愚蠢的问题,我很难理解an
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;
});
}
};
相反,我建议你使用类似的东西,这可能会使它更通用一些。检查下面的代码
(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*/}
)
}
}
]);
});
(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概念。此外,您可能还希望合并数据,而不是过度写入数据。还有一些数据存储库,您可以调查所有这类检查都将投入使用。控制器只在视图和服务之间来回传递数据,并且在页面的整个生命周期中不会像服务感谢您一样持久。我已经将这个答案作为问题的第二部分,并将在我的代码中实现它。我还有更多问题,但你们投票否决了我,所以我无法在堆栈溢出上发布新问题-(谢谢你,盖拉我把这个答案作为我问题的第一部分。