[英]How to use data from API in factory AngularJS
我有以下代码,该代码使用人员数组中的数据来计算人员工资。
'use strict'; var app = angular.module('app', []); app.factory('staffFactory', function ($http) { var staff = [ {"id": "1","name": "Kate","rate": "10", "hours": "10"}, {"id": "2","name": "John","rate": "20", "hours": "10"}, {"id": "3","name": "Matt","rate": "15", "hours": "10"} ]; function calcPayInner(){ var unique = {}, distinct = [],pay = []; for (var i in staff) { if (typeof (unique[staff[i].id]) == "undefined") { distinct.push(staff[i].id); } unique[staff[i].id] = unique[staff[i].id] || {pay:0}; unique[staff[i].id].name = staff[i].name; unique[staff[i].id].pay += (parseInt(staff[i].rate, 10) * parseInt(staff[i].hours, 10)); } for (var p in unique) { pay.push([p, unique[p]]); pay.sort(function (a, b) { return (b[1].pay - a[1].pay); }); } return pay; } var staffService = {}; staffService.allStaff = function () { return staff; }; staffService.CalcPay = function () { return calcPayInner(); }; return staffService; }); app.controller('MainCtrl', ['$scope', 'staffFactory', function ($scope, staffFactory) { $scope.staff = staffFactory.allStaff(); console.log($scope.staff); $scope.CalcPay = staffFactory.CalcPay(); $scope.keyPress = function(keyCode){ $scope.CalcPay = staffFactory.CalcPay(); }; }]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="app"> <div ng-controller="MainCtrl"> <table> <tr><td>name</td><td>rate</td><td>hours</td></tr> <tr ng-repeat="s in staff"> <td>{{s.name}}</td> <td><input ng-keyup="keyPress(s.rate)" ng-model="s.rate"></td> <td><input ng-keyup="keyPress(s.hours)" ng-model="s.hours"></td> </tr> </table> <table> <tr><td>name</td><td>pay</td></tr> <tr ng-repeat="b in CalcPay"> <td>{{b.1.name}}</td> <td>{{b.1.pay}}</td> </tr> </table> </div> </div>
所有这些都按预期工作,但是现在我想从API调用中获取人员数据,而不是硬编码数据。
我已经尝试了以下。 ( 请参阅plnkr )
var staff = [];
var test = $http.get('staff.json')
.success(function(data) {
staff = data;
console.log(staff);
});
正如我在控制台中看到的那样,这似乎返回了数据,但是我无法通过现有功能使它正常工作(返回空白数组)。
我也尝试过将函数包装在.success之后的.finally中,但是随后我的函数变得不确定。
我如何在工厂的函数中使用API数据,这样我的页面才能像最初使用硬编码数组那样工作?
正如其他人提到的那样,问题是您试图在数据可用之前获取数据。 解决此问题的方法是,如果您想保持数据的单一来源,则在工厂内部使用诺言。
下面的代码使用q
因此您必须将其注入工厂。
app.factory('staffFactory', function ($http, $q) {}
allStaff实施
/* Private var to hold the staff */
var staff = [];
// this method returns a promise
staffService.allStaff = function () {
var deferred = $q.defer();
// check if staff is already fetched from server if yes resolve the promise immediately
if (staff.length > 0) {
// we have data already. we can avoid going to server
deferred.resolve(staff); // staff holds all the data
} else {
// data is not available yet. fetch it from server
$http.get('staff.json')
.success(function(data) {
// once data is available resolve
staff = data;
deferred.resolve(data);
})
.error(function (error) {
deferred.reject(error);
});
}
return deferred.promise;
};
在控制器中。
staffFactory.allStaff().then(function (staff) {
$scope.staff = staff;
console.log($scope.staff);
$scope.CalcPay = staffFactory.CalcPay();
$scope.keyPress = function(keyCode) {
$scope.CalcPay = staffFactory.CalcPay();
};
});
检出plunkr
这是我的方法:
$scope.documents = [];
$http.post('get_xml.php')
.then(function (result) {
$scope.documents = result.data;
console.log(result.data);
});
据我所知.then
是一个异步函数,它将在数组可用时立即对其进行更新。
因此,在您的情况下,应为:
app.factory('staffFactory', function ($http) {
var staff = [];
var test = $http.get('staff.json').then(function(result) {
staff = result.data;
console.log(staff);
});
/* Rest of your code... */
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.