2013-05-16 63 views
11

我试图让角度阅读文件的内容,用户通过<input type="file"控件选择。虽然角度不具有文件上传控制指令,它应该是很容易解决,与调用$applyHTML5与AngularJS上传文件

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

不幸的是,该事件从来没有发射。这就像选择器无法引用正确的DOM元素:即使选择器找到元素,文件列表始终为空。这也会发生,如果我戳穿js控制台。 DOM检查器改为在其属性中包含文件列表。

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

回答

14

这里是我做的:

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> 

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

+0

不错。我最终在控制器中定义了一个全局函数,并从内联事件处理程序调用它。由于$ scope在外部闭包中,至少我可以$应用更改。该指令绝对是一种更“角度”的方式来做到这一点。但问题是:为什么选择器返回一个'input'元素,看起来与用户正在进行交互的元素看起来完全一样,但实际上并不是这样呢? – BruceBerry

+0

mmmh这不适合我。如果我运行你的plunkr,我总是得到 文件: { “0”:{} } 我做错了什么? – pomarc

+0

@pomarc IIRC,它用于工作......但似乎现代浏览器不支持字符串化File对象。您必须直接访问属性才能在视图中显示它们。 – Tosh

2

如果您正在使用的角度寻找文件上传你可以使用这个插件

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

它基本上是像梦呓的回答一个指令,需要照顾的非HTML5的浏览器与FileAPI闪光灯填充工具,具有$ http.uploadFile函数通过AJAX上传实际的文件。

1

site使用Angular service进行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.