5

我試圖關注此[tutorial],但無法使其工作。Angular File Upload指令不更新控制器型號

我的角度控制器正在爲我的指令中創建的模型記錄undefined。 這是一個[JSFiddle]它的工作創建了我的教程的作者。

問題是查看可以找到$scope.myFile但是控制器沒有($scope.myFileundefined)。

該視圖顯示{{ myFile.name }}(僅舉例my-image.jpg)。 myFile變量是一個包含所選文件數據的JS對象。這工作正常。該指令似乎是將所選文件的值分配給模型(並因此在視圖中正確顯示)。

<input file-model="myFile" type="file"/ > 
<div class="label label-info"> 
    {{ myFile.name }} 
</div> 
<button ng-click="uploadDocs()">Click</button> 

這是我從這[tutorial]得到的指令。

由於輸入型file不能使用ng-model,該指令設置要與file輸入相關的模型,每次分配給它的文件火災change事件。

directive('fileModel', [ 
    '$parse', 
    function ($parse) { 
     return { 
     restrict: 'A', 
     link: function(scope, element, attrs) { 
      var model = $parse(attrs.fileModel); 
      var modelSetter = model.assign; 

      element.bind('change', function(){ 
      scope.$apply(function(){ 
       if (element[0].files.length > 1) { 
       modelSetter(scope, element[0].files); 
       } 
       else { 
       modelSetter(scope, element[0].files[0]); 
       } 
      }); 
      }); 
     } 
     }; 
    } 
    ]). 

在控制器我只要登錄$scope.myFile。這是從上面HTML中的按鈕調用的。 理想情況下,我會在這裏上傳文件到服務器,但我不能,因爲$scope.myFile是未定義的。

$scope.uploadDocs = function() { 
    var file = $scope.myFile; 
    console.log($scope.myFile); 
}; 

有人能告訴我爲什麼認爲是re​​cieving $scope.myFile但控制器日誌undefined$scope.myFile

+0

嘗試初始化我的文件作爲您的控制器的第一行:'$ scope.myFile = {};'這主要是點問題 – harishr 2014-11-24 06:02:36

+1

我已經制作了你提供的代碼plunkr,它工作正常:http://plnkr.co/edit/o9D2Q6Tzkesm5MTyqXFE?p=preview – EvAlex 2014-11-24 06:09:58

+1

今天經歷了這個問題。像'uploadDocs(myfile)'這樣的將'myFile'傳遞到'uploadDocs()'函數似乎是這樣做的 – Akinwale 2016-08-21 15:29:35

回答

5

當試圖從控制器訪問指令的變量時遇到了同樣的問題。在我的情況下,我可以讓控制器使用myFile,但是我必須從指令中將它分配給scope.$parent.$parent.myFile。爲了訪問變量我不想在血統的深度硬編碼,所以我結束了使用服務共享指令和控制器之間的變量:

.factory('fileService', function() { 
    var files = []; 
    return files; 
}) 

我的指令代碼更改爲使用以服務代替attrs.fileModel這是本教程中使用:

.directive('fileModel', ['$parse', 'fileService', function ($parse, fileService) { 
    return { 
     restrict: 'A', 
     link: function(scope, element) { 
      element.bind('change', function(){ 
       scope.$apply(function(){ 
        if (element[0].files != undefined) { 
         fileService.push(element[0].files[0]); 
         console.log('directive applying with file'); 
        } 
       }); 
      }); 
     } 
    }; 
}]) 

然後,注入的FileService到控制器後,我可以直接從的FileService訪問文件:

$scope.uploadDocs = function() { 
    console.log(fileService); 
}; 
+0

同樣的問題,當你使用ng-annotate時,除非我使用服務共享變量,否則modelSetter對我無效。 – daisy 2016-07-04 03:22:41

+0

我仍然非常想知道爲什麼Q中的教程工作正常(也適用於我),但在我自己的代碼中實現它沒有 - 我得到與$ scope.myFile未定義的OP相同的錯誤。儘管如此,這個解決方案仍然有效,並且理解起來非常清楚,所以Glen贏得了獎勵。 – marlar 2016-10-11 11:03:27

0

我已經看到了教程,但選擇了使用這個庫巫婆使得文件上傳無縫: ng-file-upload

0

嘗試以下解決方案: HTML代碼:

<div class="btn-header"> 
    <label for="attachment" class="control-label">Attachment</label> 
    <div class="has-feedback"> 
     <input type="file" id="fileUpload" name="attachment" ng-disabled="BRPTab.BRPTelePhonyandTestScipt.Checked" 
       class="form-control" data-ak-file-model="BRPTab.tutorial.attachment" /> 
     <span class="form-control-feedback" aria-hidden="true"></span> 
     <div class="help-block with-errors"></div> 
    </div> 
</div> 

代碼對於服務:

AppService.factory("entityService", ["akFileUploaderService", function(akFileUploaderService) { 
    var saveTutorial = function(tutorial, url) { 

     return akFileUploaderService.saveModel(tutorial, url); 
    }; 
    return { 
     saveTutorial: saveTutorial 
    }; 
}]); 

(function() { 
    "use strict" 
    angular.module("akFileUploader", []) 
     .factory("akFileUploaderService", ["$q", "$http", 
      function($q, $http) { 
       var getModelAsFormData = function(data) { 
        var dataAsFormData = new FormData(); 
        angular.forEach(data, function(value, key) { 
         dataAsFormData.append(key, value); 
        }); 

        return dataAsFormData; 
       }; 

       var saveModel = function(data, url) { 


        var deferred = $q.defer(); 
        $http({ 
         url: url, 
         method: "POST", 
         //data: 
         // { 
         //  tutorial: getModelAsFormData(data), 
         //  Object: Obj 
         // }, 
         //params: Indata, 
         data: getModelAsFormData(data), 
         transformRequest: angular.identity, 
         headers: { 
          'Content-Type': undefined 
         } 
        }).success(function(result) { 

         deferred.resolve(result); 
        }).error(function(result, status) { 
         deferred.reject(status); 
        }); 
        return deferred.promise; 
       }; 

       return { 
        saveModel: saveModel 
       } 

      } 
     ]) 
     .directive("akFileModel", ["$parse", 
      function($parse) { 
       return { 
        restrict: "A", 
        link: function(scope, element, attrs) { 
         var model = $parse(attrs.akFileModel); 
         var modelSetter = model.assign; 
         element.bind("change", function() { 
          scope.$apply(function() { 
           modelSetter(scope, element[0].files[0]); 
          }); 
         }); 
        } 
       }; 
      } 
     ]); 
})(window, document); 

讓我知道你們是否面臨任何問題。

0

試試這個代碼

   <html> 

       <head> 
        <script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script> 
       </head> 

       <body ng-app = "myApp"> 

        <div ng-controller = "myCtrl"> 
        <input type = "file" file-model = "myFile"/> 
        <button ng-click = "uploadFile()">upload me</button> 
        </div> 

        <script> 
        var myApp = angular.module('myApp', []); 

        myApp.directive('fileModel', ['$parse', function ($parse) { 
         return { 
          restrict: 'A', 
          link: function(scope, element, attrs) { 
           var model = $parse(attrs.fileModel); 
           var modelSetter = model.assign; 

           element.bind('change', function(){ 
           scope.$apply(function(){ 
            modelSetter(scope, element[0].files[0]); 
           }); 
           }); 
          } 
         }; 
        }]); 

        myApp.service('fileUpload', ['$http', function ($http) { 
         this.uploadFileToUrl = function(file, uploadUrl){ 
          var fd = new FormData(); 
          fd.append('file', file); 

          $http.post(uploadUrl, fd, { 
           transformRequest: angular.identity, 
           headers: {'Content-Type': undefined} 
          }) 

          .success(function(){ 
          }) 

          .error(function(){ 
          }); 
         } 
        }]); 

        myApp.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){ 
         $scope.uploadFile = function(){ 
          var file = $scope.myFile; 

          console.log('file is '); 
          console.dir(file); 

          var uploadUrl = "/fileUpload"; 
          fileUpload.uploadFileToUrl(file, uploadUrl); 
         }; 
        }]); 

        </script> 

       </body> 
      </html> 
1

此問題已在幾個角版本,其中的文件對象不能設置範圍變量的觀察。由於周圍的工作做,通過現場控制器,使用此文件對象(而不是從範圍)

HTML表單上傳

<form> 
    <div class="form-group"> 
        <label for="myFileField">Select a file: </label> 
        <input type="file" file-model="myFile" /> <label>File Name:</label> 
        <input type="text" ng-model="filename"></input> 
       </div> 
       <button ng-click="uploadFile(myFile)" class="btn btn-primary">Upload File</button> 
      </form> 

控制器

$scope.uploadFile = function (file1) { 
      var file = $scope.myFile; // this is undefined 
      console.log("My file =" +file1); // you get this 
      // Make http call to upload the file or make service call   
} 

希望這解決問題

相關問題