我正在使用AngularJS 1.2.6
我正在使用$http.get()
拨打电话。我想在服务中处理响应以保持控制器清洁,然后只返回相关数据。我认为我可以直接绑定到promise,当异步调用完成后,$scope
对象上的属性将会更新,这将自动更新我的视图。
在这个例子中,我正在调用Encyclopedia of Life API来获取多媒体对象列表。我只对图像感兴趣(总是用mimeType: 'image/jpeg'
返回),这样我就可以将它们输入到图像轮播指令中。
注意:我遗漏了长网址以减少混乱
服务
.factory('GetEOL', ['$http', function ($http) {
var getPhotoList = function ( eolCode ) {
// Call API that returns multimedia objects
var promise = $http.jsonp( 'someURL' + eolCode ).then(function (response) {
var media = response.data.dataObjects, // array returned from api
slides = [];
// Grab only the images from the API response
_.each(media, function(item) {
if (item.mimeType === 'image/jpeg') {
slides.push({
image: item.eolMediaURL,
text: item.rightsHolder
});
}
});
return slides;
});
return promise;
};
return {
getPhotoList: getPhotoList
};
}]);
控制器:
.controller('ProfileImageController', ['$scope', 'GetEOL', function ($scope, GetEOL, SpeciesCodes) {
$scope.codes = {eol: 1019149};
$scope.slides = [];
$scope.interval = 5000;
// Shouldn't this automatically update my view when the promise is fulfilled??
$scope.slides = GetEOL.getPhotoList($scope.codes.eol);
}]);
查看:
<div class="col-md-3 thumbnail eol-slider">
<carousel interval="interval"> <!-- angular-ui-bootstrap directive -->
<slide ng-repeat="slide in slides" active="slide.active">
<img ng-src="{{slide.image}}" style="margin:auto;">
<div class="carousel-caption">
<p>{{slide.text}}</p>
</div>
</slide>
</carousel>
</div>
答案 0 :(得分:3)
当履行承诺时,不应该自动更新我的观点吗?
不,不再是Angular 1.2,它被认为太神奇了,所以现在你必须明确指定延续:
GetEOL.getPhotoList($scope.codes.eol).then(function(result){
$scope.slides = result;
});
引用IgorMinar的变化:
以前承诺在表达式中的表达式中的任何位置找到 评估将在未解决时评估为未定义且未评估 履行价值,如果履行。
这个功能并没有被证明是非常有用或受欢迎的, 主要是因为模板中数据访问之间的二分法 (作为原始值访问)和控制器代码(作为承诺访问)。
在大多数代码中,我们最终在控制器中手动解析promises 或者通过这种方式自动路由和统一模型访问。
自动承诺展开的其他缺点:
- 在构建组件时,通常需要接收原始承诺
- 增加了复杂性并减慢了表达式评估
由于需要生成的代码量,- 使表达式代码预生成不具吸引力
- 使IDE自动完成并支持工具支持
- 添加了太多魔法
在1.2中,您仍然可以选择加入。您只需告诉$parseProvider
$parseProvider.unwrapPromises(true)
它会像Angular 1.1那样做。
您也可以直接从服务中复制此内容而无需展开角度模板:
.then
方法(为其分配与承诺相同的值),这样它就可以自行调整,但不确定我是否非常喜欢这个想法。这是一个非常简单的实现:
var app = angular.module('app',[]);
app.controller("TestCtrl", function ($scope,MyService) {
$scope.items = MyService();
});
app.service("MyService",function($timeout){
return function getResource(){
var dat = [];
$timeout(function(){
dat.push("Hello"); // Note, DO NOT do `dat = something` here, that will break
dat.push("World"); // you must change _the same reference_
},2000);
return dat;
}
});
或者,如果你返回一个可用的 - 它看起来像:
dat.then = t.then.bind(t); // add promise methods
dat.catch = t.catch.bind(t);
dat.finally = t.catch.bind(t);
然后:
var result = MyService();
$scope.items = result;
result.then(function(){
alert("Also hooked on promise completion!");
});
答案 1 :(得分:0)
A)
$scope.slides = [];
GetEOL.getPhotoList($scope.codes.eol).then(function(result){
$scope.slides = result;
});