我是AngularJs世界的新手 - 我正在尝试从两个REST WS调用中获取数据。
第一个返回一组数据(工作正常) - 使用来自第一个数据的数据,我需要进行另一个webservice调用并检索数据并在表格中打印。
以下是我到目前为止所尝试的内容: HTML:
<table ng-table="tableParams" id="request_table" class="table table-striped table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>Number</th>
<th>Price</th>
<th>Short Description</th>
<th>Requested for</th>
<th>State</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="request in req_list | orderBy:sortType:sortReverse | filter: searchItem">
<p ng-repeat="item in fetchRequest(request.price)"></p>
<td>{{request.number }}</td>
<td>{{request.price}}</td>
<td>{{request.short_description}}</td>
<td>{{request.requested_for.display_value}}</td>
<td>{{request.stage}}</td>
</tr>
</tbody>
脚本:
angular.module('sc_request_list')
.controller('MyRequestItems', [
'$scope',
'$http',
function($scope, $http) {
$scope.sortType = 'number' //set the default sort type
$scope.sortReverse = false; // set the default sort order
$scope.searchItem // set the default search/filter term
$scope.itemUrl = '/api/sc_request';
$scope.reqUrl = '/api/sc_req_item';
$http.defaults.headers.common.Accept = "application/json";
$scope.fetchRequestItemList = function() {
$http({
method: 'GET',
url: $scope.itemUrl,
}).
success(function(data, status) {
var result = data;
var json = JSON.stringify(result);
var data = JSON.parse(json);
$scope.req_list = data.result; // response data
}).
error(function(data, status) {
$scope.req_list = [{
"req_list": "Error fetching list"
}];
});
}
$scope.fetchRequest = function(request) {
console.log("Request Number is: " + request);
$http({
method: 'GET',
url: $scope.reqUrl + "/" + request,
}).
success(function(data, status) {
var result = data;
var json = JSON.stringify(result);
var data = JSON.parse(json);
$scope.req = data.result; // response data
}).
error(function(data, status) {
$scope.req = [{
"req": "Error fetching list"
}];
});
}
}
]);
任何有助于帮助的人。
答案 0 :(得分:5)
我会这样做,第二次调用成功回复。
function getFirstItem(){ // Here I declare a function that will return a promise.
return $http({
method: 'GET',
url: $scope.itemUrl
});
}
function getDependantItem(){ // I declare a second function that returns a promise
return $http({
method: 'GET',
url: $scope.otherUrl
});
}
$scope.fetchRequest = function(request) { // Here is a function that can be called by the view.
getFirstItem()
/*
* I call the first function that returns a promise.
* the "then" is just setting a
* callback that will be executed when your server will respond.
* The next thing the code does, after registering the callback,
* is going to the end of your function,
* and return nothing.
*/
.then(function(result1){
$scope.req = result1.result; // Now that the server has answered, you can assign the value to $scope.req, and then, call the second function.
getDependantItem().then(function(result2){
// This is still an async call. The code keeps on running, and
// you will only have this callback running when your server will have responded
// Handle your response here and assign your response to a $scope variable.
}, function(error2){
// If an error happened during the second call, handle it here.
});
}, function(error1){
// If an error happened during first call, handle it here.
});
// If you want to return something, you must do it here.
// Before your promises would ever be resolved
// That's the reason why you got an undefined
};
关于您的代码,很少有注意事项:
避免.success
和.error
,请使用.then(function(success){}, function(error){});
。大多数框架都弃用了这两个第一,并且角度文档根本不再谈论它。
https://docs.angularjs.org/api/ng/service/ $ Q
避免将所有内容放入$ scope中。只需将需要与视图或其他控制器共享的内容放在一起。
尽快,了解共享功能的服务,并让1层应用程序负责1件事
答案 1 :(得分:3)
使用$ q服务,您可以链接您的承诺对象:
$scope.fn1 = function(){
var deferred = $q.defer();
$http.({ method: 'GET', url: 'YOUR_1st_API' }).success(function(data){
deferred.resolve(data);
});
return deferred.promise;
}
$scope.fn2 = function(data){
var deferred = $q.defer();
$http.({ method: 'GET', url: 'YOUR_2nd_API' }).success(function(data){
deferred.resolve(data);
});
return deferred.promise;
}
// after $scope.fn1() is done pass data with resolve method to $scope.fn2() , now you can access data from fn1 inside fn2
$scope.fn1().then($scope.fn2);
如果将业务逻辑(例如数据获取)分离到“服务”或“工厂”并将它们注入控制器,那会更好。通过这种方式,您的代码将更易于阅读和维护。
答案 2 :(得分:1)
您的调用是异步调用的,因此在进行调用时,其余代码仍在执行。因此,
<p ng-repeat="item in fetchRequest(request.price)"></p>
在request.price
被定义之前执行。
您需要做的是将呼叫链接到您的api呼叫:
$http({
method: 'GET',
url: $scope.itemUrl,
}).
success(function(data, status) {
var result = data;
var json = JSON.stringify(result);
var data = JSON.parse(json);
$scope.req_list = data.result; // response data
//Loop through requests
$scope.req_list.foreach(function (elem, index) {
//chained call is here
$scope.fetchRequest(elem.price, index);
});
}).
error(function(data, status) {
$scope.req_list = [{
"req_list": "Error fetching list"
}];
});
$scope.fetchRequest = function(request, index) {
console.log("Request Number is: " + request);
$http({
method: 'GET',
url: $scope.reqUrl + "/" + request,
}).
success(function(data, status) {
var result = data;
var json = JSON.stringify(result);
var data = JSON.parse(json);
//Attach result of api call to apropriate element of req_list array
$scope.req_list[index].items = data;
}).
error(function(data, status) {
$scope.req = [{
"req": "Error fetching list"
}];
});
}
}
&#13;
然后改变:
<p ng-repeat="item in fetchRequest(request.price)"></p>
要:
<p ng-repeat="item in request.items"></p>
答案 3 :(得分:-1)
通常我使用以下模式:
$http({method: 'GET',
url: '<*whatever url is, no need to put it on $scope, unless you really need it there*>'})
.success(function(result) { return result.data; })
.error(function(reason) { <handle your error here> })
.then(function(data) { <make your second request here with the data you've got from the first> });
答案 4 :(得分:-1)
在第一次成功通话中,您应该拨打第二个:
angular.module('sc_request_list')
.controller('MyRequestItems', [
'$scope',
'$http',
function($scope, $http) {
$scope.sortType = 'number' //set the default sort type
$scope.sortReverse = false; // set the default sort order
$scope.searchItem // set the default search/filter term
$scope.itemUrl = '/api/sc_request';
$scope.reqUrl = '/api/sc_req_item';
$http.defaults.headers.common.Accept = "application/json";
$scope.fetchRequestItemList = function() {
$http({
method: 'GET',
url: $scope.itemUrl,
}).
success(function(data, status) {
var result = data;
var json = JSON.stringify(result);
var data = JSON.parse(json);
$scope.req_list = data.result; // response data
// Second call
$scope.fetchRequest = function(request) {
console.log("Request Number is: " + request);
$http({
method: 'GET',
url: $scope.reqUrl + "/" + request,
}).
success(function(data, status) {
var result = data;
var json = JSON.stringify(result);
var data = JSON.parse(json);
$scope.req = data.result; // response data
}).
error(function(data, status) {
$scope.req = [{
"req": "Error fetching list"
}];
});
}
}).
error(function(data, status) {
$scope.req_list = [{
"req_list": "Error fetching list"
}];
});
}
}
]);