我想要做的是为单个产品上传多张图片。我无法在任何地方解决这个问题。我可以上传单张图片,但是当我尝试通过添加动态表单控件来发送多张图片时,它不起作用。
下面是我试过的代码..
Add.Component.html
<div>
<form [formGroup]="form" (ngSubmit)="submitForm()">
<div class="form-group">
<input type="file" formControlName="image" (change)="uploadFile($event)">
</div>
<div class="form-group >
<input type="text" formControlName="name">
</div>
<div class="form-group">
<button type="button" (click)="addalternateImage()">Add Alternate Image</button>
<div formArrayName="alternateImage" *ngFor="let image of alternateImage.controls; let i=index">
<input [formControlName]="i" (change)="uploadFile($event)" type="file">
</div>
</div>
<div class="form-group">
<button >Upload</button>
</div>
</form>
</div>
Add.componenet.ts
export class AddComponent implements OnInit {
name: string | any;
image: any = [];
constructor(private service: UploadService, private fb: FormBuilder) {}
ngOnInit(): void {}
// Adding alternate image control
get alternateImage() {
return this.form.get('alternateImage') as FormArray;
}
addalternateImage() {
this.alternateImage.push(this.fb.control(''));
}
form = this.fb.group({
name: [''],
alternateImage: this.fb.array([]),
})
uploadFile(event: any) {
this.alternateImage = event.target.files[0];
}
submitForm() {
const formData: any = new FormData();
formData.append("Name", this.form.controls['name'].value);
formData.append("Image", this.alternateImage, this.alternateImage.name);
}
}
我想要这样发送数据
{
"name":"productname",
"image":{ "img1" , "img2" , "img3" }
}
答案 0 :(得分:0)
我对这个问题的解决方案是保留一个单独的图像数组。图像在数组中的索引等价于它在表单中的索引。
这是假设您一次只使用一种产品。如果您有一个表单,您可以在其中动态添加产品,然后为每个产品添加图像,那么我将使用 2D 数组(图像数组的数组)。
类型脚本:
import { HttpClient } from '@angular/common/http';
import { Component } from '@angular/core';
import {
FormArray,
FormBuilder,
FormGroup,
Validators,
} from '@angular/forms';
import { Observable } from 'rxjs';
import { take } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
productImageForm: FormGroup;
images: any[];
constructor(private fb: FormBuilder, private http: HttpClient) {
this.images = [];
this.productImageForm = this.fb.group({
productName: ['', Validators.required],
images: this.fb.array([this.getImageFormGroup()]),
});
}
private getImageFormGroup() {
// keep place of added image control in images array
this.images.push(undefined);
return this.fb.group({
imagePath: [null, Validators.required],
});
}
get imagesFormArray() {
return this.productImageForm?.get('images') as FormArray;
}
public addImageForm() {
this.imagesFormArray.push(this.getImageFormGroup());
}
public removeImageForm(imageIndex: number): void {
this.imagesFormArray.removeAt(imageIndex);
// remove image from image array
this.images.splice(imageIndex, 1);
}
public onFileChange(event: any, index: number): void {
const file = event.target.files[0];
// replace image in images array
this.images.splice(index, 1, file);
if (!file) {
this.imagesFormArray.controls[index].get('imagePath')?.patchValue(null);
}
}
public submit(): void {
// check that product name has been given
// and that all image inputs have been utilized
if (this.productImageForm.valid) {
this.upload();
} else {
console.log('Form is not valid');
}
}
private upload() {
// check for max image size
this.images.forEach((file) => {
if (file.size > 10000000) {
alert('Each File should be less than 10 MB of size.');
return;
}
});
const images = new FormData();
this.images.forEach((image,) => {
images.append('fileData', image);
});
this.uploadImages(images)
.pipe(take(1))
.subscribe(
(res) => {
console.log('success');
},
(err) => {
console.log(err);
}
);
}
private uploadImages(imagesToUpload: FormData): Observable<any> {
const productName = this.productImageForm.get('productName').value;
return this.http.post('yourEndpoint/' + productName, imagesToUpload);
}
}
HTML:
<div>
<form [formGroup]="productImageForm">
<mat-form-field>
<mat-label>ProductName</mat-label>
<input matInput type="text" formControlName="productName" />
</mat-form-field>
<div formArrayName="images">
<div
class="card m-2 p-2"
*ngFor="let image of imagesFormArray.controls; let i = index"
[formGroupName]="i"
>
<div class="d-flex justify-content-between">
<input
type="file"
formControlName="imagePath"
(change)="onFileChange($event, i)"
/>
<button mat-icon-button (click)="removeImageForm(i)">
<mat-icon>remove</mat-icon>
</button>
</div>
</div>
<button mat-icon-button (click)="addImageForm()">
<mat-icon>add</mat-icon>
</button>
<button mat-rised-button (click)="submit()">Submit</button>
</div>
</form>
</div>
在这个例子中,我使用的是有棱角的材料。 如果您想使用有角度的材料,请不要忘记将必要的导入添加到您的模块中:
模块.TS
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
AppRoutingModule,
ReactiveFormsModule,
FormsModule,
BrowserAnimationsModule,
MatFormFieldModule,
MatInputModule,
MatIconModule,
MatButtonModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}