2

我正在編寫UploadService。 到目前爲止上傳工作正常。 但我想用xhr回調更新控制器的範圍,以顯示相關信息和UI。Angular:將工廠服務結果應用於示波器控制器

我該怎麼做?我認爲工廠服務不適合混淆控制器特定的東西。

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... 

回答

2

嘗試做在工廠以下內容:

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

希望它能幫助:

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工廠指令控制器內。歡呼:)

+0

完美地工作!謝謝 – faboolous

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; 
     }; 
+0

這會給我一個返回值。我更喜歡在控制器的範圍內運行一個函數,以便調整範圍變量,輸出通知等。 – faboolous