你好,我想验证输入文件html类型的图像,只接受'png', 'jpg', 'jpeg', 'gif
'且不大于2mb,直到我确定只有输入它不会占用我this.firstFormGroup.controls.image .status
时,其他任何文件都被激活为有效状态。
handleFileInput(event) {
const file = event.target.files[0];
const typeFile = file.type.split('/');
const filemb: number = file.size / 1000000;
if (filemb <= 2 && (typeFile[1] === 'png' || typeFile[1] === 'jpg' || typeFile[1] === 'jpeg' || typeFile[1] === 'gif') ) {
const filePath = `${this.rutaImg}/${file.name}`;
const fileRef = this.storage.ref(filePath);
const task = this.storage.upload(filePath, file);
this.uploadPercent = task.percentageChanges();
task.snapshotChanges().pipe(
finalize(() => {
this.downloadURL = fileRef.getDownloadURL();
this.downloadURL.subscribe( url => {
if ( url ) {
this.urlImg = url;
console.log(this.urlImg);
this.validateImage = true;
console.log(this.validateImage );
return {
isError: this.validateImage
};
}
});
})
)
.subscribe();
} else {
this.validateImage = false;
}
}
html代码
<div>
<input formControlName="image" (change)="handleFileInput($event)" type="file" id="file" class="inputfile" accept="image/*" required/>
<label for="file"><mdb-icon icon="camera"></mdb-icon> Insertar Imagen
<progress style="margin-top: -10px; " *ngIf="uploadPercent" max="100" [value]="(uploadPercent | async)"></progress>
</label>
</div>
FormGroup
this.firstFormGroup = this.fb.group({
ruc: ['', rucValidator],
razon_social: ['', nameValidator],
nameBussines: ['', nameValidator],
phone: ['', phoneValidator],
describe: ['', describeValidator],
plan: ['', Validators.required],
category: ['', Validators.required],
image: ['', this.validateImage]
});
答案 0 :(得分:0)
您必须创建一个自定义FormControl,我将向您展示如何创建它(online example),也可以使用npm模块(FileInputAccessor)
创建FormControl并上传有效文件的步骤
1。实施ControlValueAccessor
image-formcontrol.component
import { Component, OnInit, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { ImageFormcontrol } from './image-formcontrol';
@Component({
selector: 'app-image-formcontrol',
templateUrl: './image-formcontrol.component.html',
styleUrls: ['./image-formcontrol.component.css'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ImageFormcontrolComponent),
multi: true
}
]
})
export class ImageFormcontrolComponent implements OnInit, ControlValueAccessor {
_registerOnChangeFn;
_registerOnTouchedFn;
constructor() { }
ngOnInit() {
}
handleFileInput(event: Event) {
const file = (event.target as HTMLInputElement).files[0];
this.writeValue({
file
});
}
writeValue(value: ImageFormcontrol.Value) {
if (this._registerOnTouchedFn) {
this._registerOnTouchedFn();
}
if (this._registerOnChangeFn) {
// update value and validity
this._registerOnChangeFn(value);
}
}
registerOnChange(fn) {
this._registerOnChangeFn = fn;
}
registerOnTouched(fn) {
this._registerOnTouchedFn = fn;
}
}
<input (change)="handleFileInput($event)" type="file" id="file" class="inputfile" accept="image/*" />
2。添加了自定义验证规则
image-formcontrol-validator
export function allowedTypes(pattern: string[]): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } | null => {
const value = control.value as ImageFormcontrol.Value;
const valid = null;
const isUndefined = !value || !value.file;
if (isUndefined) {
return valid;
}
const allowed = new RegExp(`(${pattern.join('|')})`, 'ig').test(value.file.type);
if (allowed) {
return valid;
} else {
const invalid = { 'allowedTypes': { value: control.value } };
return invalid;
}
};
}
-
2-1。注册自定义验证规则
app.component(您可以将其更改为组件,仅用于演示目的)
export class AppComponent {
firstFormGroup: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit() {
const imageFormControl = new FormControl('', ImageFormcontrolValidator.allowedTypes(['jpeg']));
this.firstFormGroup = this.fb.group({
image: imageFormControl
});
}
}
3。以您的反应形式收听变化事件
export class AppComponent {
firstFormGroup: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit() {
const imageFormControl = new FormControl('', ImageFormcontrolValidator.allowedTypes(['jpeg']));
this.firstFormGroup = this.fb.group({
image: imageFormControl
});
imageFormControl.statusChanges.subscribe((status) => {
switch (status) {
case 'VALID':
// Upload the valid file to your storage
const value = imageFormControl.value as ImageFormcontrol.Value;
this.upload(value.file);
break;
}
});
}
private upload(file: File) {
console.log('upload', file);
/* your custom logic
const filePath = `${this.rutaImg}/${file.name}`;
const fileRef = this.storage.ref(filePath);
const task = this.storage.upload(filePath, file);
this.uploadPercent = task.percentageChanges();
task.snapshotChanges().pipe(
finalize(() => {
this.downloadURL = fileRef.getDownloadURL();
this.downloadURL.subscribe( url => {
if ( url ) {
this.urlImg = url;
console.log(this.urlImg);
this.validateImage = true;
console.log(this.validateImage );
return {
isError: this.validateImage
};
}
});
})
)
.subscribe();
*/
}
}
答案 1 :(得分:0)
我有一个可以帮助您或帮助任何人的飞弹。不是完美的,但是经过阅读和研究很多。我这样做仅是为了验证文件扩展名。
https://angular-fileupload-custom-validator-reactive-form.stackblitz.io
我在这里恢复:
为您的FormGroup或Form Builder创建自定义验证器。
将其添加到您的组件并定义允许的扩展数组 文件。
将无效或有效状态返回到您的输入表单。
答案 2 :(得分:0)
import { AbstractControl, FormControl } from "@angular/forms";
export function requiredFileType(type: string[]) {
return function(control: FormControl) {
// return (control: AbstractControl): { [key: string]: any } | null => {
const file = control.value;
const valid = null;
if (file) {
// console.log(file);
var path = file.replace(/^.*[\\\/]/, "");
// var el_down = path
// .split("\\")
// .pop()
// .split("/")
// .pop();
const extension = path.split(".")[1].toUpperCase();
console.log(extension + "extension" + type.length);
var existValue: boolean = false;
for (var i = 0; i < type.length; i++) {
let typeFile = type[i].toUpperCase();
if (typeFile === extension.toUpperCase()) {
console.log("type" + typeFile);
existValue = true;
}
}
if (existValue == true) {
return null;
} else {
return {
requiredFileType: true
};
}
return null;
}
return null;
};
}
this.addSlot
.get("FileUpload")
.setValidators([
Validators.required,
requiredFileType(["jpg", "png", "txt"])
]);
<div class="col-sm-5">
<input
type="file"
formControlName="FileUpload"
[class.is-invalid]="FileUpload.invalid && uploadPanel"
class="form-control"
(click)="handleFileInput($event.target.files)"
#inputTypeFile
/>
<!-- <button onclick="document.getElementById('abc').click()">
choose file
</button> -->
<div *ngIf="FileUpload.invalid && uploadPanel">
<small *ngIf="FileUpload.errors?.required" class="text-danger"
>File is required</small
>
<small
*ngIf="FileUpload.errors?.requiredFileType"
class="text-danger"
>File is required</small
>
</div>
</div>