Javascript AngularJS函数可用于多个控制器
在AngularJS+RestAPI中构建一个简单的控制面板 构建了一个简单的工厂,用于发出API请求Javascript AngularJS函数可用于多个控制器,javascript,angularjs,Javascript,Angularjs,在AngularJS+RestAPI中构建一个简单的控制面板 构建了一个简单的工厂,用于发出API请求(GET,POST),并向成功回调返回必要的数据。需要处理返回数据并更改$scope,因为API可能返回服务器端表单字段错误 我无法在工厂内构建处理/更改$scope,因为工厂没有(也不应该)访问该范围。我不希望在成功回调中处理/应用,因为它是重复的(每个API请求一次) 解决这个问题的最佳“角度方法”是什么 一种可能的解决方案是在角度应用程序之外存在一个函数,然后只需将$scope和必要的数据
(GET,POST)
,并向成功回调返回必要的数据。需要处理返回数据并更改$scope
,因为API可能返回服务器端表单字段错误
我无法在工厂内构建处理/更改$scope
,因为工厂没有(也不应该)访问该范围。我不希望在成功回调中处理/应用,因为它是重复的(每个API请求一次)
解决这个问题的最佳“角度方法”是什么
一种可能的解决方案是在角度应用程序之外存在一个函数,然后只需将$scope和必要的数据传递给它。
这感觉像是一个糟糕的工作环境(见下文)
为什么不在控制器中包含一个函数来处理它呢?我通常是这样处理的:
myApp.controller("saveForm", ["$scope", "api", function($scope, api), function() {
...
$scope.submit = function() {
api("POST", url, $scope.data, function(data) {
//onSuccess
processData(data);
});
}
function provessData(data){
// do stuff to data
$scope.foo = data;
}
...
}]);
您的控制器似乎做了太多的工作,并且对实际请求(url、“POST”方法等)了解太多 如何将工厂中的数据转换为控制器期望的数据。工厂不需要知道任何关于范围的事情。它只是将数据转换成控制器可以使用的格式,然后将其发送回。这样,工厂可以跨控制器重用
myApp.controller("saveForm", ["$scope", "api", function($scope, api), function() {
...
$scope.submit = function() {
// Call API.update and handle the deferred that is returned, which will be the transformed data
api.update($scope.data).then(function (transformedData) {
scope....
});
}
...
}]);
myApp.factory('api', ['$http', '$q', function($http, $q) {
return {
update : function () {
var deferred = $q.defer();
$http({
method: "GET",
url: "your/url/path"
}).success(function(data) {
var transformedData;
// Perform data transformation here instead of in controllers
angular.forEach(data, function (value, key) {
transformedData.....
});
deferred.resolve(transformedData);
});
return deferred.promise;
}
}
}]);
不确定我是否理解您,但您可以通过mixin方式扩展控制器: 基本控制器
(function() {
'use strict';
angular.module('Base', []);
function BaseController($scope, <injectables>, that) {
that.mixin1 = function() {
};
that.mixin2 = function(arg1, arg2) {
};
}
angular.module('Base').controller('BaseController',
['$scope', '...', BaseController]);
})();
(function() {
'use strict';
angular.module('Derived', ['Base']);
function DerivedController($scope, $controller, ...) {
$controller('BaseController', {
'$scope' : $scope,
...
'that' : this
});
// this.mixin1
// this.mixin2
}
angular.module('Derived').controller('DerivedController',
['$scope', '$controller', '...', DerivedController]);
})();
请注意,您可以使用Angular的
$controller
服务来混合功能。您可以创建一个工厂,返回您的processData
功能:
myApp.factory('processData', [function () {
return function(scope, data) {
angular.forEach(data, function(value, key)) {
scope....
}
};
}]);
然后通过角度注射:
myApp.controller("saveForm", ["$scope", "api", "processData", function($scope, api, processData) {
...
$scope.submit = function() {
api("POST", url, $scope.data, function(data) {
//onSuccess
processData($scope, data);
});
}
...
}]);
与在DI之外声明函数相比,这种方法的优点是,如果需要,仍然可以在单元测试中轻松模拟
processData
依赖关系。这确实有效,但是,我有多个控制器需要使用processData()。在这个实现中,我必须在每个控制器中包含函数;重复的代码。然后试试这个:好吧,那么在这种情况下,你会推荐我给出的解决方案,但感觉很混乱,因为它存在于Angular应用程序之外。此外,我认为控制器应该更通用、更具体数据、更不具体功能。您可能需要处理所有表单数据的通用表单控制器,以及处理表单功能的表单指令,而不是存储表单控制器。为什么有多个控制器处理相同的数据?我绝对不建议从角度来处理函数。在Angular中有处理util函数的解决方案。madhead的解决方案正是您当时所寻找的。创建一个base/util控制器,并将其注入到需要的地方。这确实有效,但并不能解决问题。我有多个控制器使用api
工厂,以相同的方式处理数据并更改$scope。将它放在每个成功回调中会导致大量重复代码。
myApp.controller("saveForm", ["$scope", "api", "processData", function($scope, api, processData) {
...
$scope.submit = function() {
api("POST", url, $scope.data, function(data) {
//onSuccess
processData($scope, data);
});
}
...
}]);