2

我正在开发一个多文件上传模块,但在不使用$rootScope.

指令监视文件输入并将文件onchange交给服务,在那里它们被上传并监控上传进度。根据响应(来自成功、错误和进度更改),父控制器应显示拇指和进度。

我不想在我的 上使用$emitand ,因为我需要经常安静的模式并且只有一个父控制器需要知道上传。$on$rootScope

我创建了一个简化的(!)Plunkr,其中包含一些附加信息,以更好地理解问题。

我的控制器是否有另一种方式来响应更改(发生在服务工厂内)?
或者也许是一种完全不同的方式来实现这一目标?

4

1 回答 1

3

使用 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;
  });

更新了您的 Plunker

于 2013-03-18T01:09:17.677 回答