INPUT TYPE ="文件&QUOT JavaScript的,而不是从HTML&LT显示文件的内容AngularJS的简单混合物;文件、混合物、是从、而不

2023-09-14 00:25:33 作者:毁了她的清白就要给她未来

我已经看到了使用指令使AngularJS访问一个文件的亚历克斯这样的的小提琴和博客文章),但我还以为下面这个简单的code将工作(事实并非如此)。

I have seen examples that use directives to enable AngularJS to access the content or properties of a file (for example in Alex Such's fiddle and blog post) but I would have thought the following simple code would work (it doesn't).

HTML

<body ng-app="myapp">
    <div id="ContainingDiv" ng-controller="MainController as ctrl">
        <input id="uploadInput" type="file" name="myFiles" onchange="grabFileContent()" />
        <br />
        {{ ctrl.content }}
    </div>
</body>

JavaScript的:

JavaScript:

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

myapp.controller('MainController', function () {
    this.content = "[Waiting for File]";
    this.showFileContent = function(fileContent){
        this.content = fileContent;
    };
});

var grabFileContent = function() {
    var files = document.getElementById("uploadInput").files;
    if (files && files.length > 0) {
        var fileReader = new FileReader();
        fileReader.addEventListener("load", function(event) {
            var controller = angular.element(document.getElementById('ContainingDiv')).scope().ctrl;
            controller.showFileContent(event.target.result);
        });
        fileReader.readAsText(files[0]);
    }
};

如果我把一个断点就行 this.content = fileContent 我可以看到的内容的价值从改变[等待文件],是由所选择的txt文件的内容所取代(在我的情况你好世界)。在 controller.showFileContent断点(event.target.result)显示了相同的价值变动[等待文件]到你好世界。

If I place a breakpoint on the line this.content = fileContent I can see that the value of content changes from "[Waiting for File]" and is replaced by the content of the chosen txt file (in my case "Hallo World"). A breakpoint on controller.showFileContent(event.target.result) shows the same, the value changes from "[Waiting for File]" to "Hallo World".

但绝不HTML重新渲染,它保持为[等待文件]。为什么呢?

But the HTML never re-renders, it stays as "[Waiting for File]". Why?

(注:我已经把code在小提琴。)

(N.B. I've put the code in a fiddle.)

推荐答案

在戴奇的回答看起来code 权利,肯定有助于我理解的东西。但 AngularJS不支持文件输入绑定等纳克-change 将不起作用。看着在是GitHub的问题这似乎是因为结合为HTML的文件输入和上传文件被视为同义并因为执行完整的文件的API是比较复杂的。但也有纯粹的本地的情况,我们希望从本地文件的输入加载到角度模式。

The code in deitch's answer looks right, and has certainly helped me understand things. But AngularJS does not support file input binding and so ng-change will not work. Looking at the discussion in that GitHub issue this appears to be because binding to HTML's file input and uploading the file are seen as synonymous and because implementing the full file API is more complicated. However there are purely local scenarios where we want to load input from a local file into an Angular model.

我们可以用角指令亚历克斯这样做在小提琴并的博客文章我在问题中提到,或作为 hon2a的editted答案和 Laurent的答案做的。

We could acheive this with an Angular directive as Alex Such does in the fiddle and blog post I mention in the question, or as hon2a's editted answer and laurent's answer do.

但要实现这一点没有,我们需要处理的文件输入的的onchange 外的角范围内,但然后使用角的 $范围指令。$申请( )提醒角度来产生的变化。 下面是一些code,这是否:

But to achieve this without directives we need to handle file input's onchange outside of the Angular context but then use Angular's $scope.$apply() to alert Angular to the resulting changes. Here is some code that does this:

HTML

<div id="ContainingDiv" ng-controller="MainController as ctrl">
    <input id="uploadInput" type="file" name="myFiles" onchange="grabFileContent()" />
    <br />
    {{ ctrl.content }}
</div>

JavaScript的:

JavaScript:

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

myApp.controller('MainController', ['$scope', function ($scope) {
    this.content = "[Waiting for File]";
    this.showFileContent = function(fileContent){
        $scope.$apply((function(controller){
            return function(){
                controller.content = fileContent;
            };
        })(this));
    };
}]);

var grabFileContent = function() {
    var files = document.getElementById("uploadInput").files;
    if (files && files.length > 0) {
        var fileReader = new FileReader();
        fileReader.addEventListener("load", function(event) {
           var controller = angular.element(document.getElementById('ContainingDiv')).scope().ctrl;
           controller.showFileContent(event.target.result);
        });
        fileReader.readAsText(files[0]);
    }
};