这是我的HTML表单:

<form name="myForm" ng-submit="">
    <input ng-model='file' type="file"/>
    <input type="submit" value='Submit'/>
</form>

我想从本地机器上传一个图像,并想读取上传文件的内容。所有这些我都想用AngularJS来做。

当我试图打印$scope的值时。文件是未定义的。


当前回答

app.directive('ngUpload', function () {   
  return {    
    restrict: 'A',  
    link: function (scope, element, attrs) {

      var options = {};
      options.enableControls = attrs['uploadOptionsEnableControls'];

      // get scope function to execute on successful form upload
      if (attrs['ngUpload']) {

        element.attr("target", "upload_iframe");
        element.attr("method", "post");

        // Append a timestamp field to the url to prevent browser caching results
        element.attr("action", element.attr("action") + "?_t=" + new Date().getTime());

        element.attr("enctype", "multipart/form-data");
        element.attr("encoding", "multipart/form-data");

        // Retrieve the callback function
        var fn = attrs['ngUpload'].split('(')[0];
        var callbackFn = scope.$eval(fn);
        if (callbackFn == null || callbackFn == undefined || !angular.isFunction(callbackFn))
        {
          var message = "The expression on the ngUpload directive does not point to a valid function.";
          // console.error(message);
          throw message + "\n";
        }                      

        // Helper function to create new  i frame for each form submission
        var addNewDisposableIframe = function (submitControl) {
          // create a new iframe
          var iframe = $("<iframe id='upload_iframe' name='upload_iframe' border='0' width='0' height='0' style='width: 0px; height: 0px;
border: none; display: none' />");

          // attach function to load event of the iframe
          iframe.bind('load', function () {

              // get content - requires jQuery
              var content = iframe.contents().find('body').text();

              // execute the upload response function in the active scope
              scope.$apply(function () { callbackFn(content, content !== "" /* upload completed */); });

              // remove iframe
              if (content != "") // Fixes a bug in Google Chrome that dispose the iframe before content is ready.
                setTimeout(function () { iframe.remove(); }, 250);


              submitControl.attr('disabled', null);
              submitControl.attr('title', 'Click to start upload.');
            });

          // add the new iframe to application
          element.parent().append(iframe);
        };

        // 1) get the upload submit control(s) on the form (submitters must be decorated with the 'ng-upload-submit' class)
        // 2) attach a handler to the controls' click event
        $('.upload-submit', element).click(
          function () {

            addNewDisposableIframe($(this) /* pass the submit control */);

            scope.$apply(function () { callbackFn("Please wait...", false /* upload not completed */); });



            var enabled = true;
            if (options.enableControls === null || options.enableControls === undefined || options.enableControls.length >= 0) {
              // disable the submit control on click
              $(this).attr('disabled', 'disabled');
              enabled = false;
            }

            $(this).attr('title', (enabled ? '[ENABLED]: ' : '[DISABLED]: ') + 'Uploading, please wait...');

            // submit the form
            $(element).submit();
          }
        ).attr('title', 'Click to start upload.');
      }
      else
        alert("No callback function found on the ngUpload directive.");     
    }   
  }; 
});



<form class="form form-inline" name="uploadForm" id="uploadForm"
ng-upload="uploadForm12"  action="rest/uploadHelpFile"  method="post"
enctype="multipart/form-data" style="margin-top: 3px;margin-left:
6px"> <button type="submit" id="mbUploadBtn" class="upload-submit"
ng-hide="true"></button> </form>

@RequestMapping(value = "/uploadHelpFile", method =
RequestMethod.POST)   public @ResponseBody String
uploadHelpFile(@RequestParam(value = "file") CommonsMultipartFile[]
file,@RequestParam(value = "fileName") String
fileName,@RequestParam(value = "helpFileType") String
helpFileType,@RequestParam(value = "helpFileName") String
helpFileName) { }

其他回答

你可以使用一个安全快速的FormData对象:

// Store the file object when input field is changed
$scope.contentChanged = function(event){
    if (!event.files.length)
        return null;

    $scope.content = new FormData();
    $scope.content.append('fileUpload', event.files[0]); 
    $scope.$apply();
}

// Upload the file over HTTP
$scope.upload = function(){
    $http({
        method: 'POST', 
        url: '/remote/url',
        headers: {'Content-Type': undefined },
        data: $scope.content,
    }).success(function(response) {
        // Uploading complete
        console.log('Request finished', response);
    });
}

以上接受的答案不兼容浏览器。如果有人有兼容性问题,试试这个。

小提琴

视图代码

 <div ng-controller="MyCtrl">
      <input type="file" id="file" name="file"/>
      <br>
      <button ng-click="add()">Add</button>
      <p>{{data}}</p>
    </div>

控制器代码

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

function MyCtrl($scope) {
    $scope.data = 'none';    
    $scope.add = function(){
      var f = document.getElementById('file').files[0],
          r = new FileReader();
      r.onloadend = function(e){        
          var binary = "";
var bytes = new Uint8Array(e.target.result);
var length = bytes.byteLength;

for (var i = 0; i < length; i++) 
{
    binary += String.fromCharCode(bytes[i]);
}

$scope.data = (binary).toString();

          alert($scope.data);
      }
      r.readAsArrayBuffer(f);
    }
}

简单地说

在Html中-只添加以下代码

     <form name="upload" class="form" data-ng-submit="addFile()">
  <input type="file" name="file" multiple 
 onchange="angular.element(this).scope().uploadedFile(this)" />
 <button type="submit">Upload </button>
</form>

当你点击“上传文件按钮”时,这个函数被调用。它将上传文件。你可以安慰它。

$scope.uploadedFile = function(element) {
$scope.$apply(function($scope) {
  $scope.files = element.files;         
});
}

在控制器中添加更多-以下代码添加到函数中。这个函数在你点击按钮时被调用,这个按钮被用来“命中api (POST)”。它将发送文件(上传)和表单数据到后端。

var url = httpURL + "/reporttojson"
        var files=$scope.files;

         for ( var i = 0; i < files.length; i++)
         {
            var fd = new FormData();
             angular.forEach(files,function(file){
             fd.append('file',file);
             });
             var data ={
              msg : message,
              sub : sub,
              sendMail: sendMail,
              selectUsersAcknowledge:false
             };

             fd.append("data", JSON.stringify(data));
              $http.post(url, fd, {
               withCredentials : false,
               headers : {
                'Content-Type' : undefined
               },
             transformRequest : angular.identity
             }).success(function(data)
             {
                  toastr.success("Notification sent successfully","",{timeOut: 2000});
                  $scope.removereport()
                   $timeout(function() {
                    location.reload();
                }, 1000);

             }).error(function(data)
             {
              toastr.success("Error in Sending Notification","",{timeOut: 2000});
              $scope.removereport()
             });
        }

在这种情况下…我添加了下面的代码作为表单数据

var data ={
          msg : message,
          sub : sub,
          sendMail: sendMail,
          selectUsersAcknowledge:false
         };

这应该是对@jquery-guru的答案的更新/评论,但由于我没有足够的代表,它将在这里。它修复了现在由代码生成的错误。

https://jsfiddle.net/vzhrqotw/

变化主要是:

FileUploadCtrl.$inject = ['$scope']
function FileUploadCtrl(scope) {

To:

app.controller('FileUploadCtrl', function($scope)
{

如果需要,请随意搬到更合适的地方。

您的文件和json数据同时上传。

// FIRST SOLUTION var _post = function (file, jsonData) { $http({ url: your url, method: "POST", headers: { 'Content-Type': undefined }, transformRequest: function (data) { var formData = new FormData(); formData.append("model", angular.toJson(data.model)); formData.append("file", data.files); return formData; }, data: { model: jsonData, files: file } }).then(function (response) { ; }); } // END OF FIRST SOLUTION // SECOND SOLUTION // If you can add plural file and If above code give an error. // You can try following code var _post = function (file, jsonData) { $http({ url: your url, method: "POST", headers: { 'Content-Type': undefined }, transformRequest: function (data) { var formData = new FormData(); formData.append("model", angular.toJson(data.model)); for (var i = 0; i < data.files.length; i++) { // add each file to // the form data and iteratively name them formData.append("file" + i, data.files[i]); } return formData; }, data: { model: jsonData, files: file } }).then(function (response) { ; }); } // END OF SECOND SOLUTION