从AngularJS中的<input />显示所选文件

时间:2015-11-28 15:33:56

标签: javascript angularjs filereader

我有一个使用标准Javascript的工作示例,但我希望使用AngularJS更加本地化。

具体来说,我需要使用用户选择的文件的文件名来更新范围。

这是我使用原生Javascript实现的内容:

<span>
    <input  ng-model="uploadDownloads" type="file" style="visibility:hidden; width: 1px;" id=uploadDownloads name=uploadDownloads onchange="$(this).parent().find('span').html($(this).val().replace('C:\\fakepath\\', ''))"  /> <!-- Chrome security returns 'C:\fakepath\'  -->
    <input  class="btn btn-primary" type="button" value="choose file" onclick="$(this).parent().find('input[type=file]').click();"/> <!-- on button click fire the file click event -->
    <span  class="badge badge-important" ></span>
</span> 

文件阅读器功能已经是角度:

$scope.add = function(valid){
        if(valid){
                $scope.data = 'none';
                var f = document.getElementById('uploadDownloads').files[0];
                var r = new FileReader();
                r.onloadend = function(e){
                    $scope.data = e.target.result;
                    $scope.notPass = false;
                    $modalInstance.close({
                        'data':$scope.data,
                        'fileName':$scope.fileName,
                        'fileExplain':$scope.fileExplain
                    });
                };
            /*activate the onloadend to catch the file*/
                r.readAsBinaryString(f);
        } else {
            $scope.notPass = true;
        }
    };

问题是使用Angular而不是JavaScript激活oncl​​ick和onchange,以便使用所选文件名更新我的<span>

1 个答案:

答案 0 :(得分:1)

此问题建立在现有question and answer之上。但是,具体来说,我已经修改了that answer中的代码,以适应这里看似具体的问题,这就是如何更新<span>以便用户选择文件名为&<body ng-controller="AppController"> <input ng-model="uploadDownloads" type="file" fd-input file-name="fileName"/> <span class="badge badge-important">Output here: {{fileName}}</span> </body> 对于angularjs而言,这是惯用的。

这是一个codepen,带有工作样本。

这里是html文件的相关部分:

fd-input

这里的关键是你有一个名为file-name的自定义指令,它对它定义的一个名为$scope的属性有双向绑定。您可以将一个(function() { 'use strict'; angular.module('app', []) .controller('AppController', AppController) .directive('fdInput', fdInput); function AppController($scope) { $scope.fileName = ''; } function fdInput() { return { scope: { fileName: '=' }, link: function(scope, element, attrs) { element.on('change', function(evt) { var files = evt.target.files; console.log(files[0].name); console.log(files[0].size); scope.fileName = files[0].name; scope.$apply(); }); } } }; })(); 变量传递给该属性,该指令将文件名绑定到该属性。这是控制器和指令。

file-name

如上所述,该指令直接来自another SO answer。我修改了它以添加一个范围,该范围对... return { scope: { fileName: '=' }, ... 属性进行双向绑定:

files[0].name

然后我将... scope.fileName = files[0].name; scope.$apply(); ... 分配给双向绑定:

{{1}}

签出codepen。应该这样做。您可以在指令中使用父作用域,但这不是一个好主意,因为它限制您在每个控制器使用此指令一次。此外,如果要列出多个文件,则必须更新此代码以返回这些文件的数组。

希望得到这个帮助。