【问题标题】:HTML5 File upload with AngularJS使用 AngularJS 上传 HTML5 文件
【发布时间】:2013-05-10 20:58:06
【问题描述】:

我正在尝试获取角度来读取用户通过<input type="file" 控件选择的文件的内容。即使 Angular 没有文件上传控件的指令,通过调用 $apply 应该很容易解决这个问题:

function MyController($scope) {
  $('#myFile').on('change', function() {
    var that = this;
    $scope.$apply(function() { $scope.files = that.files });
  });
}

不幸的是,该事件从未被触发。就像选择器无法引用正确的 DOM 元素一样:即使选择器找到了该元素,文件列表也始终为空。如果我用 js 控制台四处寻找,也会发生这种情况。 DOM 检查器的属性中包含文件列表。

这让我发疯,但到目前为止,我让它工作的唯一方法是使用分配给全局变量的内联事件处理程序。为什么 jquery 选择器返回另一个项目?是否有一些模板编译的 Angular 会混淆选择器?

【问题讨论】:

    标签: html file-upload angularjs


    【解决方案1】:

    这是我的工作:

    http://plnkr.co/edit/JPxSCyrxosVXfZnzEIuS?p=preview

    app.directive('filelistBind', function() {
      return function( scope, elm, attrs ) {
        elm.bind('change', function( evt ) {
          scope.$apply(function() {
            scope[ attrs.name ] = evt.target.files;
            console.log( scope[ attrs.name ] );
          });
        });
      };
    });
    

    模板:

    <input type="file" filelist-bind name="files"/>
    <p>selected files : <pre>{{ files | json }}</pre></p>
    

    这种任务,你肯定要使用指令。 但我认为您主要关心的是如何访问所选文件 对象和我的例子应该澄清这一点。

    【讨论】:

    • 不错。我最终在控制器中定义了一个全局函数,并从内联事件处理程序中调用它。由于 $scope 在外部闭包中,至少我可以 $apply 更改。该指令绝对是一种更“有角度”的方式来做到这一点。但问题是:为什么选择器返回的input 元素看起来与用户正在交互的元素一模一样,但实际上并非如此?
    • mmmh 这对我不起作用。如果我运行你的 plunkr,我总是得到文件:{ "0": {} } 我做错了吗?
    • @pomarc IIRC,它曾经可以工作......但现代浏览器似乎不支持字符串化 File 对象。您必须直接访问属性才能在视图中显示它们。
    • 这是 Tosh 示例的一个分支,适用于现代浏览器。 plnkr.co/edit/peDONwopzkEeELg3cRvR?p=preview
    【解决方案2】:

    如果您正在寻找 Angular 文件上传,您可以使用此插件

    https://github.com/danialfarid/angular-file-upload

    它基本上是一个类似于 tosh 回答的指令,它使用 FileAPI flash polyfill 处理非 HTML5 浏览器,并具有 $http.uploadFile 函数来通过 AJAX 上传实际文件。

    【讨论】:

      【解决方案3】:

      这个site 使用 Angular 服务进行 HTML5 文件上传。一种简单的方法是设置一个控制器,该控制器调用服务并在异步调用完成时更新 UI。

      控制器:

       myapp.controller('fileUploadCtrl', ['$scope', '$q', 'FileInputService', function ($scope, $q, FileInputService) {
                  $scope.fileInputContent = "";
                  $scope.onFileUpload = function (element) {
                      $scope.$apply(function (scope) {
                          var file = element.files[0];
                          FileInputService.readFileAsync(file).then(function (fileInputContent) {
                              $scope.fileInputContent = fileInputContent;
                          });
                      });
                  };
              }]);
      

      服务:

      myapp.service('FileInputService', function ($q) {
      
          this.readFileAsync = function (file) {
              var deferred = $q.defer(),
              fileReader = new FileReader(),
              fileReader.readAsText(file);
      
              fileReader.onload = function (e) {
                  deferred.resolve(e.target.result);
              };
              return deferred.promise;
          };
      });
      

      模板:

      Choose File <input type="file" onchange="angular.element(this).scope().onFileUpload(this)">
      <br />
      {{fileInputContent}}
      

      参考:你可以找到完整的源代码和参考on this site.

      【讨论】:

        猜你喜欢
        • 2018-02-09
        • 2013-09-05
        • 2011-12-12
        • 2012-09-08
        • 2013-12-27
        • 2016-08-31
        相关资源
        最近更新 更多