4

私は UploadService を書いています。これまでのアップロードは正常に機能しています。しかし、関連する情報と UI を表示するために、コントローラーのスコープを xhr コールバックで更新したいと考えています。

どうすればいいですか?ファクトリ サービスは、コントローラー固有のものでごちゃごちゃするのに適した場所ではないと思います。

adminServices.factory('UploadService', [function() {
  return {
    beginUpload: function(files, options) {
        var xhr = new XMLHttpRequest();
        xhr.upload.addEventListener("progress", this.onUploadProgress, false);
        xhr.addEventListener("load", this.onUploadComplete, false);
        xhr.addEventListener("error", this.onUploadFailed, false);
        xhr.addEventListener("abort", this.onUploadCanceled, false);
    },
    onUploadProgress: function(progress) {
      console.log("upload progress"); //HERE I CAN'T UPDATE the CONTROLLER's SCOPE
    },
    onUploadComplete: function(result) {
      console.log("upload complete"); //NOR HERE
    },


app.directive('fileUpload', function() {
   return {
      restrict: 'E',
      scope: {},
      template: '', //omitted for brevity
      controller: function($scope, UploadService) {
         $scope.upload = function() {             
             UploadService.beginUpload($scope.files, options);
         };
      //HERE I'D LIKE TO HAVE NOTIFICATIONS OF THE onXYZ methods...
4

2 に答える 2

4

工場で次のことを試してください。

adminServices.factory('UploadService', [function() {
  //Create a UploadService Class

  function UploadService (scope) { //Constructor. Receive scope.      
    //Set Class public properties
    this.scope = scope;
    this.xhr = new XMLHttpRequest();
    //Write any initialisation code here. But reserve event handlers for the class user.
  }

  //Write the beginUpload function
  UploadService.prototype.beginUpload = function (files, options) {
    //Upload code goes here. Use this.xhr
  }

  //Write the onUploadProgress event handler function
  UploadService.prototype.onUploadProgress = function (callback) {
    var self = this;
    this.xhr.upload.addEventListener("progress", function (event) {
       //Here you got the event object.
       self.scope.$apply(function(){
         callback(event);//Execute callback passing through the event object.
         //Since we want to update the controller, this must happen inside a scope.$apply function 
       });
    }, false);
  }

  //Write other event handlers in the same way
  //...

  return UploadService;
}]);

UploadServiceこれで、次のようにディレクティブ コントローラー内でファクトリを使用できます。

app.directive('fileUpload', function() {
  return {
    restrict: 'E',
    scope: {},
    template: '', //omitted for brevity
    controller: function($scope, UploadService) {
      //Create an UploadService object sending the current scope through the constructor.
      var uploadService = new UploadService($scope);

      //Add a progress event handler 
      uploadService.onUploadProgress(function(event){
        //Update scope here.
        if (event.lengthComputable) {
          $scope.uploadProgress = event.loaded / event.total;
        }
      });

      $scope.upload = function() {             
        uploadService.beginUpload($scope.files, options);
      };

それが役に立てば幸い。乾杯 :)

于 2013-12-10T22:19:00.347 に答える
0

スコープのオブジェクトをファクトリの戻り値またはオブジェクトにバインドしてみてください。例えば:

controller: function($scope, UploadService) {
         $scope.upload = function() {             
             UploadService.beginUpload($scope.files, options);
             $scope.uploadProgress = UploadService.onUploadProgress();
         };

次に、工場で:

onUploadProgress: function(progress) {
      return "Some message";
    },

次に、ビュー/html で:

<div>{{ uploadProgress }}</div>

または試してください:

return {
    theProgress: "",
    beginUpload: function(files, options) {...},
    onUploadProgress: function(progress) {
      theProgress = "some value";
    }
}

それから:

controller: function($scope, UploadService) {
         $scope.upload = function() {             
             UploadService.beginUpload($scope.files, options);
             $scope.uploadProgress = UploadService.theProgress;
         };
于 2013-12-10T19:19:15.843 に答える