我似乎无法理解 AngularJS 中“ promise ”的概念,我正在使用 RESTANGLE 库通过 REST 获取资源,但是我总是得到空结果。这是代码
.service('CareersService', [ 'Restangular', '$sce', function(Restangular, $sce){
var vacancies = [];
var result;
this.getVacancies = function() {
Restangular.all('job_posts').getList({active: 'true'}).then(function(job_posts){
job_posts.forEach(function(job_post){
vacancies.push(_.pick(job_post,['id','title','min_experience','max_experience','location']));
})
})
return vacancies;
}
this.getVacancy = function(job_id){
Restangular.one('job_posts',job_id).get().then(function(job_post){
result = _.pick(job_post, 'title','min_experience','max_experience','location','employment_type','description');
var safe_description = $sce.trustAsHtml(result.description);
var emp_type = _.capitalize(result.employment_type);
_.set(result, 'description', safe_description);
_.set(result, 'employment_type', emp_type);
});
return result;
}
}]).controller('DetailsCtrl', ['$scope' ,'$stateParams', 'CareersService' ,function($scope, $stateParams, CareersService) {
$scope.data.vacancy = { title: 'Loading ...', contents: '' };
$scope.data.vacancy = CareersService.getVacancy($stateParams.job_id);
}])
然后在 View 中
<div class="container">
<a ui-sref="careers" class="btn btn-primary">Show All</a>
<div class="row">
<h2>{{ data.vacancy.title }}</h2>
<p>{{ data.vacancy.min_experience }}</p>
<p>{{ data.vacancy.max_experience }}</p>
<p>{{ data.vacancy.location }}</p>
<p>{{ data.vacancy.employment_type }}</p>
<p ng-bind-html="data.vacancy.description"></p>
</div>
</div>
我在使用 Promise 的过程中是否遗漏了一些东西?
<小时/>更新
这是更新后的代码,感谢我在这里得到的所有帮助,
this.getVacancies = function() {
Restangular.all('job_posts').getList({active: 'true'}).then(function(job_posts){
job_posts.forEach(function(job_post){
vacancies.push(_.pick(job_post,['id','title','min_experience','max_experience','location']));
})
return vacancies;
})
}
this.getVacancy = function(job_id){
Restangular.one('job_posts',job_id).get().then(function(job_post){
vacancy = _.pick(job_post, 'title','min_experience','max_experience','location','employment_type','description');
...
return vacancy;
});
}
}])
在 Controller 中
CareersService.getVacancy($stateParams.job_id).then(function (vacancy){
$scope.data.vacancy = vacancy;
});
和
CareersService.getVacancies().then(function (vacancies){
$scope.data.vacancies = vacancies;
});
我现在收到错误
无法读取未定义的属性“then”
在线
CareersService.getVacancies().then(function(vacancies) {
最佳答案
Restangular 通过 http 进行 API 调用,一旦调用,它就会返回底层的 Promise 对象。在其.then
函数中可以获取API响应的数据。
因此,您在这里进行异步调用,并认为它以同步方式发生,就像您可以看到您从 Restangular 返回了
调用,这样 result
/vacancies
数组一样result
/vacancies
始终为空。
在这种情况下,您应该从服务方法返回一个 promise 。并从 Promise 返回适当的格式化数据,以便您也可以在 Controller 中链接
该 Promise(通过检索数据)。
服务
this.getVacancies = function() {
//returned Restangular promise
return Restangular.all('job_posts').getList({
active: 'true'
}).then(function(job_posts) {
job_posts.forEach(function(job_post) {
vacancies.push(_.pick(job_post, ['id', 'title', 'min_experience', 'max_experience', 'location']));
});
//return calculated result
return vacancies;
})
}
this.getVacancy = function(job_id) {
//returned Restangular promise
return Restangular.one('job_posts', job_id).get().then(function(job_post) {
result = _.pick(job_post, 'title', 'min_experience', 'max_experience', 'location', 'employment_type', 'description');
var safe_description = $sce.trustAsHtml(result.description);
var emp_type = _.capitalize(result.employment_type);
_.set(result, 'description', safe_description);
_.set(result, 'employment_type', emp_type);
//returned result to chain promise
return result;
});
}
正如我现在所说,您可以通过在服务方法调用上使用 .then
函数轻松地在 Controller 内链接 Promise。
CareersService.getVacancy($stateParams.job_id).then(function(result){
$scope.data.vacancy = result;
});
<小时/>
更新
不带 .then
的语法也可以使用,但您需要在方法调用后添加 .$object
来对其进行一些小的更改。
$scope.data.vacancy = CareersService.getVacancy($stateParams.job_id).$object;
$object
是由 Restangular
添加到 Promise 对象内部的属性。在进行 API 调用时,它会将 $scope.data.vacancy
值设置为空白数组 ([]
),一旦服务器响应响应,它就会填充该值服务器收到响应的对象。在后台,它仅更新 $object
属性的值,该属性会自动更新 $scope.data.vacancy
值。
ngResource
的 $resource
中也有相同的行为。
我还想指出,当您链接 Promise 时,您必须显式处理错误情况。而在当前代码中,您还没有处理这种失败情况。因此,我建议您也通过在 Restangular
REST API 调用中添加 error
函数来实现这一点。并使用 $q.reject('我的错误数据,这也可以是对象')
。
关于javascript - 在 AngularJS 中使用延迟结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38934419/