【发布时间】:2019-03-08 09:21:59
【问题描述】:
如何在角度材质中使用输入类型文件
您好,我正在使用棱角材料进行设计。当我进入 Angular Material 网站时,没有输入类型的文件元素。任何人都知道这件事。
【问题讨论】:
-
是的,可能但我想要这种格式
标签: angular angular-material material-design
如何在角度材质中使用输入类型文件
您好,我正在使用棱角材料进行设计。当我进入 Angular Material 网站时,没有输入类型的文件元素。任何人都知道这件事。
【问题讨论】:
标签: angular angular-material material-design
如果您想要的只是一个显示良好的文件输入按钮,这里有一个解决方法。
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
【讨论】:
onFileSelected($event)函数中添加$event会更好,所以你不需要id="file"in输入。
Angular Material 尚不支持文件上传的解决方法。 有其他方法可以归档这个。例如使用外部库。
angular-material-fileupload:link to npm package
支持的功能:
ngx-material-file-input:Link to repository
支持的功能:
ngx-mat-file-input 组件,用于 Angular Material mat-form-field
FileValidator 和 maxContentSize,用于限制文件大小ByteFormatPipe 将文件大小格式化为人类可读的格式更新
如果您只需要没有外部库的解决方法,请在此处查看答案 https://stackoverflow.com/a/53546417/6432698
【讨论】:
【讨论】:
让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>
【讨论】:
如果您不想使用一些奇怪的解决方法,那么不要将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();
}
【讨论】:
创建指令 -
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>
【讨论】: