如何在工厂 AngularJS 中使用来自 API 的数据
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 调用中获取员工数据,而不是硬编码数据。
我试过下面的方法。 (see plnkr)
var staff = [];
var test = $http.get('staff.json')
.success(function(data) {
staff = data;
console.log(staff);
});
这似乎是 return 我在控制台中看到的数据,但我无法使用我现有的函数使其工作(return 是一个空白数组)。
我也曾尝试在 .success 之后将函数包装在 .finally 中,但随后我的函数变为未定义。
如何在工厂的函数中使用 API 数据,以便让我的页面像最初使用硬编码数组一样工作?
我是这样做的:
$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... */
});
其他人提到的问题是您试图在数据可用之前获取数据。如果你想保持数据的单一来源,这个问题的解决方案是在你的工厂内部使用承诺。
下面的代码使用了 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
我有下面的代码,它使用员工数组中的数据来计算员工的工资。
'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 调用中获取员工数据,而不是硬编码数据。
我试过下面的方法。 (see plnkr)
var staff = [];
var test = $http.get('staff.json')
.success(function(data) {
staff = data;
console.log(staff);
});
这似乎是 return 我在控制台中看到的数据,但我无法使用我现有的函数使其工作(return 是一个空白数组)。
我也曾尝试在 .success 之后将函数包装在 .finally 中,但随后我的函数变为未定义。
如何在工厂的函数中使用 API 数据,以便让我的页面像最初使用硬编码数组一样工作?
我是这样做的:
$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... */
});
其他人提到的问题是您试图在数据可用之前获取数据。如果你想保持数据的单一来源,这个问题的解决方案是在你的工厂内部使用承诺。
下面的代码使用了 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