Angular 6+响应式表单实现多组图片转Base64上传后端
解决方案:Angular响应式表单中动态上传图片并转为Base64
我来帮你搞定这个问题!目前你的动态表单已经能实现字段增减,但文件输入默认只会保存文件路径,咱们需要监听文件选择事件,用FileReader把图片转成Base64编码,再更新对应的表单控件值。下面是具体的实现步骤和修改后的代码:
1. 在Component中添加文件转Base64的方法
首先在FileuploaderCuComponent里新增一个工具方法,负责读取文件并将其转为Base64,同时更新对应的表单控件:
import {Component, OnInit} from '@angular/core'; import {FormGroup, FormArray, FormControl} from '@angular/forms'; @Component({ selector: 'app-services-cu', templateUrl: '../pages/fileuploader-cu.component.html' }) export class FileuploaderCuComponent implements OnInit { uploader: FormGroup; constructor() { } ngOnInit() { this.uploader = new FormGroup({ sections: new FormArray([ this.initSection(), ]), }); } initSection() { return new FormGroup({ beforeImage: new FormControl(''), afterImage: new FormControl('') }); } addSection() { const control = <FormArray> this.uploader.get('sections'); control.push(this.initSection()); } getSections(form) { return form.controls.sections.controls; } removeSection(i) { const control = <FormArray> this.uploader.get('sections'); control.removeAt(i); } // 新增:文件转Base64并更新表单控件 onFileChange(event: Event, control: FormControl) { const file = (event.target as HTMLInputElement).files?.[0]; if (!file) return; const reader = new FileReader(); reader.onload = (e) => { // 将Base64结果设置到表单控件 control.setValue(e.target?.result); }; reader.readAsDataURL(file); } onSubmit(form) { console.log(this.uploader.value); } }
2. 修改模板,绑定文件选择事件
接下来修改HTML模板,给每个文件输入框添加(change)事件绑定,把当前选择的文件和对应的表单控件传递给上面的方法。另外注意你模板里afterImage的label写错成了Before,顺便修正一下:
<div class="row"> <div class="col-md-12 col-sm-12 col-xs-12"> <div class="x_panel"> <form [formGroup]="uploader" novalidate (ngSubmit)="onSubmit(uploader)"> <!--- Section --> <div class="row"> <div formArrayName="sections"> <div class="row" *ngFor="let section of getSections(uploader); let i = index"> <div class="col-md-12 col-sm-12 col-xs-12"> <div [formGroupName]="i"> <!---Uploader Section --> <div class="col-sm-12 col-md-4"> <div class="input-group margin-bottom-sm"> <label>Before:</label> <!-- 绑定change事件,传递当前控件 --> <input type="file" formControlName="beforeImage" accept=".jpeg, .jpg, .png" class="form-control" (change)="onFileChange($event, section.get('beforeImage'))"> <span style="font-size:12px;">(Formats:jpeg, jpg, png Size: 1MB)</span> </div> </div> <div class="col-sm-12 col-md-4"> <div class="input-group margin-bottom-sm"> <!-- 修正label为After --> <label>After:</label> <!-- 绑定change事件,传递当前控件 --> <input type="file" formControlName="afterImage" accept=".jpeg, .jpg, .png" class="form-control" (change)="onFileChange($event, section.get('afterImage'))"> <span style="font-size:12px;">(Formats:jpeg, jpg, png Size: 1MB)</span> </div> </div> <!---End of Uploader Section --> </div> <br> <button type="button" (click)="addSection()" class="btn btn-info btn-sm">Add More</button> <button type="button" class="btn btn-danger btn-sm" *ngIf="getSections(uploader).length > 1" (click)="removeSection(i)">Remove Section </button> </div> </div> </div> </div> <!-- End Section --> </form> <pre> {{uploader.value | json}} </pre> </div> </div> </div>
3. 工作原理说明
- 当用户选择图片时,
(change)事件触发onFileChange方法; - 方法中获取选择的文件,用
FileReader的readAsDataURL方法读取文件,这个方法会将文件编码为Base64格式的Data URL; - 读取完成后触发
onload事件,将结果设置到对应的表单控件中,替换原来的文件路径; - 动态新增的section也会自动绑定事件,因为
*ngFor循环时每个section都会生成带事件绑定的文件输入框。
现在你选择图片后,打开控制台或者看页面上的pre标签,就能看到表单控件里已经保存的是Base64编码的图片字符串了,提交的时候就可以直接传给后端啦!
内容的提问来源于stack exchange,提问作者Jinto Antony
相关产品推荐
相关产品推荐

