Angular 文件输入更改仅显示在第一个组件中
Angular file input changes only shows in the first component
我有一个由两种输入类型组成的图像组件:
1- 文字输入
2-文件输入
image.html
<div>
<mat-card>
<mat-card-content>
<label for="cam">Take picture</label>
<input id="cam" style="display: none;" type="file" accept="image/*" capture="camera" (change)="onSelectFile($event)" /> <br>OR<br>
<label for="gallery">Open gallery</label>
<input id="gallery" style="display: none;" type="file" accept="image/*" multiple (change)="onSelectFile($event)" />
</mat-card-content>
<img *ngFor="let image of imagesList" [src]="imagesMap.get(image)" mat-card-avatar (click)="deleteImage(image)"> <br/>
<br>
<mat-card-header *ngIf="imagesList.length > 0">
<mat-card-subtitle>Click on image to remove it</mat-card-subtitle>
</mat-card-header>
</mat-card>
<input type="text" placeholder="Ex. pat@example.com">
image.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-image',
templateUrl: './image.component.html',
styleUrls: ['./image.component.css']
})
export class ImageComponent implements OnInit {
files!: File[];
imagesMap: Map<string, string> = new Map<string, string>();
imagesList: string[] = new Array<string>();
url = "";
constructor() { }
ngOnInit(): void {
}
onSelectFile(event: any) {
this.files = event.target.files;
if (this.files && this.files.length > 0) {
for (let file of this.files) {
if (!this.imagesMap.has(file.name)) {
let url: string = "";
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = (event) => {
//@ts-ignore
url = event.target.result;
this.imagesMap.set(file.name, url);
this.imagesList.push(file.name);
}
}
}
}
}
deleteImage(imageName: string) {
let indexToRemove = this.imagesList.indexOf(imageName);
if (indexToRemove != -1) {
this.imagesList.splice(indexToRemove, 1);
this.imagesMap.delete(imageName);
indexToRemove = this.files.findIndex(file => file.name == imageName);
if (indexToRemove != -1)
this.files.splice(indexToRemove, 1);
}
}
}
问题是当我多次调用此组件或从应用程序组件中复制它时,
app.component.html
<app-image></app-image>
<app-image></app-image>
从第二个或第三个……组件中选择的图像,它总是显示在第一个组件中,这个问题与类型 File 的输入有关,输入类型文本工作正常。请参考下图以获得更清晰的视图。
Component screenshot
我想在第二个组件(相同组件但重复)中添加图片时,它们必须显示在第二个组件中。每个重复的组件必须独立于其他组件。
请帮我解决这个问题。
谢谢
那是因为重复的 Id。您有两个 ID 为 cam 和 gallery 的输入,因此当您单击第二个时,一个浏览器会找到第一个元素并打开文件选择器。这意味着你基本上点击了第一个元素。不要使用这种方法,只需使用 template variable
<label (click)="file.click()">Open gallery</label>
<input #file style="display: none;" type="file"
accept="image/*" multiple (change)="onSelectFile($event)"/>
我有一个由两种输入类型组成的图像组件: 1- 文字输入 2-文件输入
image.html
<div>
<mat-card>
<mat-card-content>
<label for="cam">Take picture</label>
<input id="cam" style="display: none;" type="file" accept="image/*" capture="camera" (change)="onSelectFile($event)" /> <br>OR<br>
<label for="gallery">Open gallery</label>
<input id="gallery" style="display: none;" type="file" accept="image/*" multiple (change)="onSelectFile($event)" />
</mat-card-content>
<img *ngFor="let image of imagesList" [src]="imagesMap.get(image)" mat-card-avatar (click)="deleteImage(image)"> <br/>
<br>
<mat-card-header *ngIf="imagesList.length > 0">
<mat-card-subtitle>Click on image to remove it</mat-card-subtitle>
</mat-card-header>
</mat-card>
<input type="text" placeholder="Ex. pat@example.com">
image.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-image',
templateUrl: './image.component.html',
styleUrls: ['./image.component.css']
})
export class ImageComponent implements OnInit {
files!: File[];
imagesMap: Map<string, string> = new Map<string, string>();
imagesList: string[] = new Array<string>();
url = "";
constructor() { }
ngOnInit(): void {
}
onSelectFile(event: any) {
this.files = event.target.files;
if (this.files && this.files.length > 0) {
for (let file of this.files) {
if (!this.imagesMap.has(file.name)) {
let url: string = "";
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = (event) => {
//@ts-ignore
url = event.target.result;
this.imagesMap.set(file.name, url);
this.imagesList.push(file.name);
}
}
}
}
}
deleteImage(imageName: string) {
let indexToRemove = this.imagesList.indexOf(imageName);
if (indexToRemove != -1) {
this.imagesList.splice(indexToRemove, 1);
this.imagesMap.delete(imageName);
indexToRemove = this.files.findIndex(file => file.name == imageName);
if (indexToRemove != -1)
this.files.splice(indexToRemove, 1);
}
}
}
问题是当我多次调用此组件或从应用程序组件中复制它时,
app.component.html
<app-image></app-image>
<app-image></app-image>
从第二个或第三个……组件中选择的图像,它总是显示在第一个组件中,这个问题与类型 File 的输入有关,输入类型文本工作正常。请参考下图以获得更清晰的视图。
Component screenshot
我想在第二个组件(相同组件但重复)中添加图片时,它们必须显示在第二个组件中。每个重复的组件必须独立于其他组件。
请帮我解决这个问题。 谢谢
那是因为重复的 Id。您有两个 ID 为 cam 和 gallery 的输入,因此当您单击第二个时,一个浏览器会找到第一个元素并打开文件选择器。这意味着你基本上点击了第一个元素。不要使用这种方法,只需使用 template variable
<label (click)="file.click()">Open gallery</label>
<input #file style="display: none;" type="file"
accept="image/*" multiple (change)="onSelectFile($event)"/>