使用Angular材料上传文件

Wre*_*all 47 html javascript file-upload angularjs angular-material

我正在使用AngularJS和角度材料编写一个Web应用程序.问题是在角度材料中没有用于文件输入的内置组件.(我觉得文件上传不适合材料设计,但我需要在我的应用程序中)

你有解决这个问题的好方法吗?

Rad*_*eth 49

leocaseiro很好的解决方案

<input class="ng-hide" id="input-file-id" multiple type="file" />
<label for="input-file-id" class="md-button md-raised md-primary">Choose Files</label>
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

codepen中查看

  • 但是,如果你想真正给用户一些关于他们选择的文件的反馈(比如`<input type ="file">`do),那么看看其他解决方案. (6认同)
  • 此外,即使您将 tabindex="0" 放在标签和输入键上,标签的行为也不正确。 (2认同)

ryn*_*nop 14

对于Angular 6+:

HTML:

<input #csvInput hidden="true" type="file" onclick="this.value=null" (change)="csvInputChange($event)" accept=".csv"/>
<button mat-flat-button color="primary" (click)="csvInput.click()">Choose Spreadsheet File (CSV)</button>
Run Code Online (Sandbox Code Playgroud)

组成方法:

  csvInputChange(fileInputEvent: any) {
    console.log(fileInputEvent.target.files[0]);
  }
Run Code Online (Sandbox Code Playgroud)

注意:此过滤器仅允许.csv文件。

  • 它强制发生“改变”事件。例如:您选择“me.jpg”,您的 Angular 应用程序将显示预览客户端。然后,您注意到“me.jpg”未正确裁剪,因此您在 Photoshop 中修改“me.jpg”,然后返回到您的 Web 应用程序,单击按钮并再次选择“me.jpg”。如果不设置“this.value=null”,您在页面上重新渲染图像的逻辑将永远不会触发。所以没有必要,但在我看来这是一个很好的做法。 (6认同)

Jun*_*per 13

基于这个答案.我花了一些时间才使这种方法有效,所以我希望我的回答可以节省一些人的时间.

CodePen上的DEMO

指示:

angular.module('app').directive('apsUploadFile', apsUploadFile);

function apsUploadFile() {
    var directive = {
        restrict: 'E',
        templateUrl: 'upload.file.template.html',
        link: apsUploadFileLink
    };
    return directive;
}

function apsUploadFileLink(scope, element, attrs) {
    var input = $(element[0].querySelector('#fileInput'));
    var button = $(element[0].querySelector('#uploadButton'));
    var textInput = $(element[0].querySelector('#textInput'));

    if (input.length && button.length && textInput.length) {
        button.click(function (e) {
            input.click();
        });
        textInput.click(function (e) {
            input.click();
        });
    }

    input.on('change', function (e) {
        var files = e.target.files;
        if (files[0]) {
            scope.fileName = files[0].name;
        } else {
            scope.fileName = null;
        }
        scope.$apply();
    });
}
Run Code Online (Sandbox Code Playgroud)

upload.file.template.html

<input id="fileInput" type="file" class="ng-hide">
<md-button id="uploadButton"
           class="md-raised md-primary"
           aria-label="attach_file">
    Choose file
</md-button>
<md-input-container md-no-float>
    <input id="textInput" ng-model="fileName" type="text" placeholder="No file chosen" ng-readonly="true">
</md-input-container>
Run Code Online (Sandbox Code Playgroud)

  • @treaz我在我的回答中添加了CodePen演示.请享用;) (2认同)

Art*_*ich 13

另一个解决方案的例子.将如下所示 在此输入图像描述

CodePen链接那里.

  <choose-file layout="row">
    <input id="fileInput" type="file" class="ng-hide">
    <md-input-container flex class="md-block">
      <input type="text" ng-model="fileName" disabled>
      <div class="hint">Select your file</div>
    </md-input-container>
    <div>
      <md-button id="uploadButton" class="md-fab md-mini">
        <md-icon class="material-icons">attach_file</md-icon>
      </md-button>
    </div>
  </choose-file>   

.directive('chooseFile', function() {
    return {
      link: function (scope, elem, attrs) {
        var button = elem.find('button');
        var input = angular.element(elem[0].querySelector('input#fileInput'));

        button.bind('click', function() {
          input[0].click();
        });

        input.bind('change', function(e) {
          scope.$apply(function() {
            var files = e.target.files;
            if (files[0]) {
              scope.fileName = files[0].name;
            } else {
              scope.fileName = null;
            }
          });
        });
      }
    };
  });
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你!


Chr*_*s L 12

来自jameswyse,网址https://github.com/angular/material/issues/3310

HTML

<input id="fileInput" name="file" type="file" class="ng-hide" multiple>
<md-button id="uploadButton" class="md-raised md-primary"> Choose Files </md-button>
Run Code Online (Sandbox Code Playgroud)

CONTROLLER

    var link = function (scope, element, attrs) {
    const input = element.find('#fileInput');
    const button = element.find('#uploadButton');

    if (input.length && button.length) {
        button.click((e) => input.click());
    }
}
Run Code Online (Sandbox Code Playgroud)

为我工作.

  • 这是最简单的方法.但是,我将md-button切换为="inputid"的标签,因此您无需绑定您的点击.标签本身就是这样做的.式.<input class ="ng-hide"id ="FileUploadInput"multiple type ="file"/> <label for ="FileUploadInput"class ="md-button md-raised md-primary">选择文件</ label> (5认同)

Aka*_*wad 10

使用 Angular 材质
HTML

<div (click)="uploadFile.click()">
   <button mat-raised-button color="primary">Choose File</button>
   <input #uploadFile (change)="upload($event)" type='file' style="display:none"/> 
</div>
Run Code Online (Sandbox Code Playgroud)

ts

upload(event:Event){
   console.log(event)
}
Run Code Online (Sandbox Code Playgroud)

堆栈闪电战


小智 7

我加入了此处发布的一些信息以及使用 Angular Material 个性化组件的可能性,这是我的贡献,无需外部库和反馈,并将所选文件的名称输入字段:

在此输入图像描述

在此输入图像描述

超文本标记语言

<mat-form-field class="columns">
    <mat-label *ngIf="selectedFiles; else newFile">{{selectedFiles.item(0).name}}</mat-label>
    <ng-template #newFile>
        <mat-label>Choose file</mat-label>
    </ng-template>
    <input matInput disabled>
    <button mat-icon-button matSuffix (click)="fileInput.click()">
        <mat-icon>attach_file</mat-icon>
    </button>
    <input hidden (change)="selectFile($event)" #fileInput type="file" id="file">
</mat-form-field>
Run Code Online (Sandbox Code Playgroud)

TS

selectFile(event) {
    this.selectedFiles = event.target.files;
}
Run Code Online (Sandbox Code Playgroud)


Wre*_*all 6

我找到了一种方法来避免样式化我自己的选择文件按钮.

因为我使用flowjs进行可恢复上传,所以我可以使用ng-flow中的" flow-btn "指令,它提供了一个具有材料设计风格的选择文件按钮.

请注意,将输入元素包装在md按钮内将不起作用.