用Angular处理异步操作的正确方法是使用promises。
您可以从服务呼叫中返回承诺并将其解析为拇指的src
。你可以不使用任何指令。
你的控制器将使用该服务是这样的:
function ParentController($scope, imageService) {
$scope.change = function() {
$scope.src = imageService.change();
$scope.then(function(result) {
// the loading ended, but there is no need to set the src
// as it will already bind to src when ends.
}, function(err) {
// something went wrong
});
};
}
您的服务:
app.factory('imageService', function($q, $rootScope) {
function doTheUploading(defer) {
if (everythingOk) {
defer.resolve(thumbSrcString);
} else {
defer.reject({something: 'an error ocurred'});
}
}
return {
change: function() {
// creates the promise
var defer = $q.defer();
doSomethingAsync(defer);
return defer.promise;
}
};
});
至少,你的HTML应该是这样的:
<div ng-controller="ParentController">
<img src="{{ src }}"><br><br>
<span class="btn" ng-click="change()">Change!</span>
</div>
关于进度,您将需要使用回调或返回可带来承诺和进度的对象指标(即:return {promise: defer.promise, percent: 0}
)。应该从服务内部更新进度指示器。
你也可以链中的承诺,如果你之前设置需要从服务器返回的URL进行任何改造它的src
财产,即:
$scope.src = imageService.change().then(function(result) {
return 'http://dummyimage.com/' + result;
});
更新your Plunker。
非常感谢您的非常详细的答案:)我查看了承诺API,但我有一个关于进度的问题:只有在解决或拒绝后,我才会返回承诺和进度,对吗?这意味着进展是100或0。但是“进行中”是一个持续的事件。当我不得不使用'$ emit'来取得进展时,对所有事情使用事件都没有意义吗? – 2013-03-18 16:46:10
确实,返回对象的想法非常不寻常。另一个解决方案(我宁愿)将使用回调。将回调传递给服务('imageService.change(this.handleOnProgress)'),并不断调用它来告知服务内部的进度。我目前在Angular promises中实现['promise.progress'](https://github.com/kriskowal/q#progress-notification),但是我不知道它是否会被接受/批准,如果它获得批准,我们不知道它何时会发货,所以如果您需要及时,最好还是回拨。 – 2013-03-18 16:58:02
不错,谢谢你的帮助:)我希望它获得批准。 – 2013-03-18 17:02:06