You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 03:59:11