我正在开发一个多文件上传模块,在使用$rootScope
从我的服务与控制器进行通信时遇到困难。
指令监视文件输入并将文件onchange
交给服务,在那里上传文件并监控上传进度。根据响应(来自成功,错误和进度变化),父控制器应显示拇指和进度。
我不想在我的$emit
上使用$on
和$rootScope
,因为我需要经常安静的模式,只有一个父控制器需要知道上传。
我创建了一个简化的(!) Plunkr ,其中包含一些其他信息,以便更好地了解问题。
我的控制器是否有另一种方式对变化作出反应(在服务工厂内发生)? 或者可能是一种完全不同的实现方式?
答案 0 :(得分:3)
使用promises处理异步操作的正确方法是使用your Plunker。
您可以从服务电话中返回承诺并将其解析为拇指的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>
关于进度,你需要使用回调或返回一个带来promise和进度指示器的对象(即:return {promise: defer.promise, percent: 0}
)。然后应该从服务内部更新进度指示器。
如果您需要对服务器返回的URL进行任何转换,然后再将其设置为src
属性,即:
$scope.src = imageService.change().then(function(result) {
return 'http://dummyimage.com/' + result;
});
更新了{{3}}。