【问题标题】:How to use input type file in angular material如何在角度材料中使用输入类型文件
【发布时间】:2019-03-08 09:21:59
【问题描述】:

如何在角度材质中使用输入类型文件

您好,我正在使用棱角材料进行设计。当我进入 Angular Material 网站时,没有输入类型的文件元素。任何人都知道这件事。

【问题讨论】:

标签: angular angular-material material-design


【解决方案1】:

如果您想要的只是一个显示良好的文件输入按钮,这里有一个解决方法。

HTML

<button type="button" mat-raised-button (click)="fileInput.click()">Choose File</button>
<input hidden (change)="onFileSelected()" #fileInput type="file" id="file">

组件

onFileSelected() {
  const inputNode: any = document.querySelector('#file');

  if (typeof (FileReader) !== 'undefined') {
    const reader = new FileReader();

    reader.onload = (e: any) => {
      this.srcResult = e.target.result;
    };

    reader.readAsArrayBuffer(inputNode.files[0]);
  }
}

受此 Angular Material Github 问题评论的启发 https://github.com/angular/material2/issues/3262#issuecomment-309000588

【讨论】:

  • 使用 Angular ay 代替查询选择器不是更好吗?喜欢@ViewChild 吗?
  • 我认为在onFileSelected($event)函数中添加$event会更好,所以你不需要id="file"in输入。
【解决方案2】:

Angular Material 尚不支持文件上传的解决方法。 有其他方法可以归档这个。例如使用外部库。

angular-material-fileuploadlink to npm package

支持的功能

  • 拖放
  • 常见上传
  • 进度条
  • 文件大小等等...

ngx-material-file-inputLink to repository

支持的功能

  • ngx-mat-file-input 组件,用于 Angular Material mat-form-field
  • FileValidatormaxContentSize,用于限制文件大小
  • ByteFormatPipe 将文件大小格式化为人类可读的格式
  • 还有更多小的次要功能...

更新

如果您只需要没有外部库的解决方法,请在此处查看答案 https://stackoverflow.com/a/53546417/6432698

【讨论】:

    【解决方案3】:

    我建议你结帐@angular-material-components/file-input

    它非常符合 Angular 材质。

    【讨论】:

      【解决方案4】:

      style the default input element of type file using the ::file-selector-button 看起来像有角度的材质按钮更有意义。此外,这种方式还考虑了用户体验,通过显示文件名让用户知道要上传的文件已添加到表单中。

      附:样式是在检查后从声明中复制的 角垫凸起按钮

      input[type="file"]::file-selector-button {
        box-shadow: 0px 3px 1px -2px rgb(0 0 0 / 20%), 0px 2px 2px 0px rgb(0 0 0 / 14%), 0px 1px 5px 0px rgb(0 0 0 / 12%);
        background: #ffd740;
        box-sizing: border-box;
        position: relative;
        -webkit-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
        cursor: pointer;
        outline: none;
        border: none;
        -webkit-tap-highlight-color: transparent;
        display: inline-block;
        white-space: nowrap;
        text-decoration: none;
        vertical-align: baseline;
        text-align: center;
        margin: 0;
        min-width: 64px;
        line-height: 36px;
        padding: 0 16px;
        border-radius: 4px;
        overflow: visible;
        transform: translate3d(0, 0, 0);
        transition: background 400ms cubic-bezier(0.25, 0.8, 0.25, 1), box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1);
        margin: 1rem;
      }
      
      
      /*  fallback for older browsers supporting the -webkit prefix */
      
      input[type="file"]::-webkit-file-upload-button {
        box-shadow: 0px 3px 1px -2px rgb(0 0 0 / 20%), 0px 2px 2px 0px rgb(0 0 0 / 14%), 0px 1px 5px 0px rgb(0 0 0 / 12%);
        background: #ffd740;
        box-sizing: border-box;
        position: relative;
        -webkit-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
        cursor: pointer;
        outline: none;
        border: none;
        -webkit-tap-highlight-color: transparent;
        display: inline-block;
        white-space: nowrap;
        text-decoration: none;
        vertical-align: baseline;
        text-align: center;
        margin: 0;
        min-width: 64px;
        line-height: 36px;
        padding: 0 16px;
        border-radius: 4px;
        overflow: visible;
        transform: translate3d(0, 0, 0);
        transition: background 400ms cubic-bezier(0.25, 0.8, 0.25, 1), box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1);
        margin: 1rem;
        font-weight: 500;
      }
      <form>
        <label for="fileUpload">Add file</label>
        <input type="file" id="fileUpload">
      </form>

      【讨论】:

        【解决方案5】:

        如果您不想使用一些奇怪的解决方法,那么不要将input 放入mat-form-field。您可以将其放在mat-form-field 之外,但仍将值包含在FormGroup 中。检查示例

        <form [formGroup]="someForm"  (ngSubmit)="onSubmit()">
                    <!--input outside the form-field-->
                    <input type="file" (Change)="onChange($event)"/>
                    <mat-form-field>
                        <!--input inside the form-field-->
                        <input matInput formControlName="someFCN">
                    </mat-form-field>
                    <button mat-raised-button>Submit</button>
        </form>
        
        
        
        
        import { FormBuilder, FormGroup, Validators } from '@angular/forms';
        
        someForm: FormGroup;
        
        constructor(private formBuilder: FormBuilder) {}
        ngOnInit(): void {
            this.someForm = this.formBuilder.group({
                  someFCN: [{ value:'', disabled: false },Validators.required],
                  file: { value:'', disabled: false }
                });
        }
        
        onChange(event: Event) {
            /*not sure what you want to do with file, i'll just set
            selected file´s name as value, but obviously u can do much more than just get file´s name.*/
            
            this.someForm.controls['file'].setValue(event.target.files[0].name);
        }
        
        onSubmit() {
            return this.someForm.getRawValue();
        }
        

        【讨论】:

          【解决方案6】:

          创建指令 -

          import { Directive, ElementRef, EventEmitter, Inject, Output } from '@angular/core';
          import { DOCUMENT } from '@angular/common';
          
          @Directive({
            selector: '[appFileUpload]'
          })
          export class FileUploadDirective {
            @Output() fileContent: EventEmitter<ArrayBuffer | string> = new EventEmitter();
          
            constructor(private elementRef: ElementRef, @Inject(DOCUMENT) private document: Document) {
              this.elementRef.nativeElement.addEventListener('click', () => {
                const input = this.document.createElement('input');
                input.type = 'file';
                input.onchange = ev => {
                  const file = (ev.target as HTMLInputElement).files?.item(0);
                  const reader = new FileReader();
                  reader.onload = e => {
                    this.fileContent.next(reader.result!);
                    input.value = '';
                  };
                  switch (file?.type) {
                    case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
                      reader.readAsArrayBuffer(file!);
                      break;
                    default:
                      reader.readAsText(file!);
                  }
                };
                input.click();
                input.remove();
              });
            }
          }
          
          

          然后像使用它一样 -

           <button appFileUpload (fileContent)="uploadDump($event)" mat-menu-item><mat-icon>upload_file</mat-icon></button>
           
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-09-10
            • 2019-05-07
            • 2018-07-20
            • 2017-01-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-04-01
            相关资源
            最近更新 更多