使用 FormBuilder 和 formdata 在 angular 中上传文件
Upload file in angular using FormBuilder & formdata
我想知道如何使用 angular 和表单生成器上传文件,目前我只找到了使用表单生成器和单个文件的教程
我的问题是 .ts
文件,如何将文件附加到 formbuilder 中的字段?我已经看到它用 formData()
完成,但无法让它们一起工作,非常感谢任何提示!
component.ts
ngOnInit() {
this.escolaridad_candidato = this.fb.group({
nivel_estudio: [, [Validators.required]],
escuela: [, [Validators.required]],
graduacion: [, [Validators.required]],
certificado: [, [Validators.required]] <--This is the file I need to append
});
}
onEstudiosChange(event) {
const reader = new FileReader();
if (event.target.files && event.target.files.length) {
const [file] = event.target.files;
reader.readAsDataURL(file);
reader.onload = () => {
this.exp_academica.patchValue({
certificado: reader.result
});
// need to run CD since file load runs outside of zone
this.cd.markForCheck();
};
}
}
// On Submit button
this.myservice.post('myUrl', this.escolaridad_candidato.rawdata(), configOptions )
component.html
<form [formGroup]="escolaridad_candidato" >
<div class="col s6 center-align" >
<p >Estudios</p>
<div class="row">
<div class="col s12">
<p >Degree</p>
<select class="browser-default" formControlName="nivel_estudio">
<option value="" disabled selected>----</option>
<option *ngFor="let nivel of listnivelEstudios" value="{{ nivel.id }}">
{{ nivel.nombre }}
</option>
</select>
</div>
<div class="col s12 center-align input-field">
<p >Escuela </p>
<input id="escuela" type="text" class="validate browser-default" formControlName="escuela"/>
</div>
<div class="col s12 input-field center-align">
<p >Año de graduación </p>
<input id="graduacion" type="text" class="validate browser-default"
formControlName="graduacion" />
</div>
</div>
<div class="row">
<div class="col s12">
<p >Certificate </p>
<div class="file-field input-field">
<div class="btn" >
<span>Adjuntar archivo +</span>
<input type="file" formControlName="certificado" (change)="onEstudiosChange($event)">
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text">
</div>
</div>
</div>
</div>
</div>
</form>
我已经为 Angular 7 和小于 7 但大于 2 的任何版本指定了代码。
formDataProductImagePost(endPoint, formData) {
let headers = new Headers();
let formDataFinal = new FormData();
// The below for loop is for multiple file uploads. If you have only one file which needs to be uploaded then you don't need the loop.
for (let j = 0; j < formData.length; j++) {
formDataFinal.append('file', formData[j]);
}
return this.http.post(this.profileApiUrl + endPoint, formDataFinal, {
headers: headers
}).toPromise().then((response: any) => {
let image_id = JSON.parse(response._body)['response'];
// console.log(image_id);
return image_id;
});
}
/// This shall work on Angular 7. Let me know if you face any issues :).
<form [formGroup]="myForm">
<div class="form-group form-inline">
<label class="btn btn-secondary btn-file">Browse
<input name="file" type="file" (change)="onFileChange($event)">
<input type="hidden" name="fileHidden" formControlName="file"/>
<!-- Validation Field -->
</label>
<p *ngIf="file" class="pl-4 align-middle mb-0">{{file.name}}</p>
</div>
<button type="button" class="btn btn-primary" (click)="finalUpload()">Upload</button>
</form>
// Angular Code
public file: string = '';
public fileN = new FormControl();
ngOnInit() {
let self = this;
this.myForm = this.formBuilder.group({
fileN: [fileName, Validators.required]
});
}
finalUpload() {
this.uploadData().subscribe(data => {
console.log(data);
});
}
uploadData():Observable<any> {
let formData = new FormData();
let result = Object.assign({}, this.myForm.value);
for (let o in result) {
formData.append(o, result[o])
}
return this.request.post<any>('http://localhost:8000/api/image', formData);
}
handleError(error: any) {
return error;
// console.log(error);
}
onFileChange($event) {
this.file = $event.target.files[0]; // <--- File Object for future use.
let file = $event.target.files[0]; // <--- File Object for future use.
this.myForm.controls['fileN'].setValue(file ? file.name : ''); // <-- Set Value for Validation
}
关于如何执行此操作的文档太少了,这很奇怪。
答案比较简单:
html 必须有这样的输入
<input type="file" (change)="onFileChanged($event, i)">
使用 fb,您可以使用类似的方式提取表单的值
const myFormValue = this.myForm.value
.ts 文件中:
public onFileChanged(event: any) {
if (event.target.files && event.target.files.length) {
const file = event.target.files[0];
this.certEscolar = file;
}
}
submit() {
const myFormValue = this.myForm.value
const myFormData = new FormData();
for ( let i = 0; i < myFormValue.length; i++ ) {
for ( let key of myFormValue) {
myFormData.append(key, myFormValue[key]);
}
}
this.http.post<any>(SOMEURL, myFormData, Config.api.multiContentOptions)
.subscribe(response => {
console.log("response from server!", response)
}
我用的headers是:
Config.ts
const MultipartHeaders: HttpHeaders = new HttpHeaders({
Authorization: 'Token ' + token,
Accept: 'application/json'
});
let Config = {
api: {
baseURL: 'http://11.98.155.150/back/ws' //obviously fake
options: { headers: jsonheaders },
formatOptions: { headers : formDheaders },
multiContentOptions: { headers : MultipartHeaders },
}
};
使用 formArrays 和 FormData 会变得更加棘手,如果有人要求我可以上传示例。
我想知道如何使用 angular 和表单生成器上传文件,目前我只找到了使用表单生成器和单个文件的教程
我的问题是 .ts
文件,如何将文件附加到 formbuilder 中的字段?我已经看到它用 formData()
完成,但无法让它们一起工作,非常感谢任何提示!
component.ts
ngOnInit() {
this.escolaridad_candidato = this.fb.group({
nivel_estudio: [, [Validators.required]],
escuela: [, [Validators.required]],
graduacion: [, [Validators.required]],
certificado: [, [Validators.required]] <--This is the file I need to append
});
}
onEstudiosChange(event) {
const reader = new FileReader();
if (event.target.files && event.target.files.length) {
const [file] = event.target.files;
reader.readAsDataURL(file);
reader.onload = () => {
this.exp_academica.patchValue({
certificado: reader.result
});
// need to run CD since file load runs outside of zone
this.cd.markForCheck();
};
}
}
// On Submit button
this.myservice.post('myUrl', this.escolaridad_candidato.rawdata(), configOptions )
component.html
<form [formGroup]="escolaridad_candidato" >
<div class="col s6 center-align" >
<p >Estudios</p>
<div class="row">
<div class="col s12">
<p >Degree</p>
<select class="browser-default" formControlName="nivel_estudio">
<option value="" disabled selected>----</option>
<option *ngFor="let nivel of listnivelEstudios" value="{{ nivel.id }}">
{{ nivel.nombre }}
</option>
</select>
</div>
<div class="col s12 center-align input-field">
<p >Escuela </p>
<input id="escuela" type="text" class="validate browser-default" formControlName="escuela"/>
</div>
<div class="col s12 input-field center-align">
<p >Año de graduación </p>
<input id="graduacion" type="text" class="validate browser-default"
formControlName="graduacion" />
</div>
</div>
<div class="row">
<div class="col s12">
<p >Certificate </p>
<div class="file-field input-field">
<div class="btn" >
<span>Adjuntar archivo +</span>
<input type="file" formControlName="certificado" (change)="onEstudiosChange($event)">
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text">
</div>
</div>
</div>
</div>
</div>
</form>
我已经为 Angular 7 和小于 7 但大于 2 的任何版本指定了代码。
formDataProductImagePost(endPoint, formData) {
let headers = new Headers();
let formDataFinal = new FormData();
// The below for loop is for multiple file uploads. If you have only one file which needs to be uploaded then you don't need the loop.
for (let j = 0; j < formData.length; j++) {
formDataFinal.append('file', formData[j]);
}
return this.http.post(this.profileApiUrl + endPoint, formDataFinal, {
headers: headers
}).toPromise().then((response: any) => {
let image_id = JSON.parse(response._body)['response'];
// console.log(image_id);
return image_id;
});
}
/// This shall work on Angular 7. Let me know if you face any issues :).
<form [formGroup]="myForm">
<div class="form-group form-inline">
<label class="btn btn-secondary btn-file">Browse
<input name="file" type="file" (change)="onFileChange($event)">
<input type="hidden" name="fileHidden" formControlName="file"/>
<!-- Validation Field -->
</label>
<p *ngIf="file" class="pl-4 align-middle mb-0">{{file.name}}</p>
</div>
<button type="button" class="btn btn-primary" (click)="finalUpload()">Upload</button>
</form>
// Angular Code
public file: string = '';
public fileN = new FormControl();
ngOnInit() {
let self = this;
this.myForm = this.formBuilder.group({
fileN: [fileName, Validators.required]
});
}
finalUpload() {
this.uploadData().subscribe(data => {
console.log(data);
});
}
uploadData():Observable<any> {
let formData = new FormData();
let result = Object.assign({}, this.myForm.value);
for (let o in result) {
formData.append(o, result[o])
}
return this.request.post<any>('http://localhost:8000/api/image', formData);
}
handleError(error: any) {
return error;
// console.log(error);
}
onFileChange($event) {
this.file = $event.target.files[0]; // <--- File Object for future use.
let file = $event.target.files[0]; // <--- File Object for future use.
this.myForm.controls['fileN'].setValue(file ? file.name : ''); // <-- Set Value for Validation
}
关于如何执行此操作的文档太少了,这很奇怪。
答案比较简单:
html 必须有这样的输入
<input type="file" (change)="onFileChanged($event, i)">
使用 fb,您可以使用类似的方式提取表单的值
const myFormValue = this.myForm.value
.ts 文件中:
public onFileChanged(event: any) {
if (event.target.files && event.target.files.length) {
const file = event.target.files[0];
this.certEscolar = file;
}
}
submit() {
const myFormValue = this.myForm.value
const myFormData = new FormData();
for ( let i = 0; i < myFormValue.length; i++ ) {
for ( let key of myFormValue) {
myFormData.append(key, myFormValue[key]);
}
}
this.http.post<any>(SOMEURL, myFormData, Config.api.multiContentOptions)
.subscribe(response => {
console.log("response from server!", response)
}
我用的headers是:
Config.ts
const MultipartHeaders: HttpHeaders = new HttpHeaders({
Authorization: 'Token ' + token,
Accept: 'application/json'
});
let Config = {
api: {
baseURL: 'http://11.98.155.150/back/ws' //obviously fake
options: { headers: jsonheaders },
formatOptions: { headers : formDheaders },
multiContentOptions: { headers : MultipartHeaders },
}
};
使用 formArrays 和 FormData 会变得更加棘手,如果有人要求我可以上传示例。