在 AngularJS + Rest API中构建一个简单的控制面板。
构建一个简单的工厂,生成API请求(GET, POST)
并将必要的数据返回到成功回调。需要处理返回数据并更改$scope
,因为API可以返回服务器端表单字段错误。
我无法在工厂内构建处理/更改$scope
,因为工厂没有(并且不应该)访问范围。我不希望在成功回调中处理/应用,因为它会重复(每个API请求一次)。
什么是最好的" Angular方式"解决这个问题?
一种可能的解决方案是在Angular应用程序之外存在一个函数,然后只传递$ scope和必要的数据。
这感觉就像是一个糟糕的工作(见下文)。
myApp.controller("saveForm", ["$scope", "api", function($scope, api), function() {
...
$scope.submit = function() {
api("POST", url, $scope.data, function(data) {
//onSuccess
processData($scope, data);
});
}
...
}]);
myApp.factory('api', ['$http', function($http) {
return function(method, url, input, success, error) {
//Retrieve data from API. Note that factory DOES NOT have access to $scope.
$http(...
}
}]);
var processData = function(scope, data) {
angular.forEach(data, function(value, key)) {
scope....
}
}
答案 0 :(得分:1)
我不确定是否有你,但你可以以混合方式扩展控制器:
基本控制器
(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
服务来混合功能。
答案 1 :(得分:0)
为什么不在控制器中包含一个处理它的函数?这就是我通常处理它的方式:
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;
}
...
}]);
答案 2 :(得分:0)
看起来你的控制器做了太多工作并且对实际请求了解太多(网址,&#34; POST&#34;等等)。
如何将工厂中的数据转换为控制器所期望的内容。工厂不需要了解范围。它只是将数据转换为控制器可以使用的格式,然后将其发送回去。通过这种方式,工厂可以在控制器之间重复使用。
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;
}
}
}]);
答案 3 :(得分:0)
您可以创建一个返回processData
函数的工厂:
myApp.factory('processData', [function () {
return function(scope, data) {
angular.forEach(data, function(value, key)) {
scope....
}
};
}]);
然后用angular注入它:
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
依赖关系仍然很容易。