一个组件的角度事件发射器与另一个组件混淆



背景

我有两个组件图像输入单和一个测试容器。image input single是一个"dumb"组件,它简化了选择图像、获取压缩文件及其url的过程。

它的Typescript文件和HTML文件如下所示

@Component({
selector: "app-image-input-single",
templateUrl: "./image-input-single.component.html",
styleUrls: ["./image-input-single.component.scss"]
})
export class ImageInputSingleComponent implements OnInit {
@Input()
image ? : string;
@Input()
circular!: boolean;
@Output()
imageAdded = new EventEmitter < Image > ();
@Output()
imageRemoved = new EventEmitter < Image > ();
onImageClear = () => {
console.log("Image clear");
if (this.image) {
this.imageRemoved.emit({
image: this.image
});
}
};
constructor(
private ng2ImgMax: Ng2ImgMaxService,
public sanatizer: DomSanitizer
) {}
ngOnInit() {
console.log(this.image);
}
onFileChanged(event: any) {
if (event.target.files && event.target.files[0]) {
const rawImage = event.target.files[0];
this.ng2ImgMax.compressImage(rawImage, 0.2).subscribe(
result => {
const file = new File([result], result.name);
const reader = new FileReader();
// @ts-ignore
reader.onload = (pe: ProgressEvent) => {
this.imageAdded.emit({
// @ts-ignore
image: pe.target.result,
imageFile: file
});
};
reader.readAsDataURL(file);
},
error => {
console.log(error);
}
);
}
}
}
<input type="file" (change)="onFileChanged($event)" accept="image/*" multiple id="imageInput">
<div [ngClass]="{'boxCircular': circular,
'box': true}">
<label for="imageInput">
<mat-icon *ngIf="!image; else imageTemp" class="camIcon">camera_alt</mat-icon>
<ng-template #imageTemp>
<button mat-icon-button class="cancelButton" (click)="onImageClear()" type="button">
<mat-icon class="cancelIcon">cancel</mat-icon>
</button>
<img [src]="sanatizer.bypassSecurityTrustUrl(image)" [ngClass]="{'profilePic': circular, 'book': !circular}">
</ng-template>
</label>
</div>

然后我有一个简单的组件,它包含两个图像输入实例单个

import { Component, OnInit } from "@angular/core";
import { Image } from "src/app/models/Image";
@Component({
selector: "app-test",
templateUrl: "./test.component.html",
styleUrls: ["./test.component.scss"]
})
export class TestComponent implements OnInit {
constructor() {}
image1?: Image;
image2?: Image;
imageAdd1 = (image: Image) => {
console.log("1");
this.image1 = image;
};
imageAdd2 = (image: Image) => {
console.log("2");
this.image2 = image;
};
imageRemove1 = (image: Image) => {
this.image1 = image;
};
imageRemove2 = (image: Image) => {
this.image2 = image;
};
ngOnInit() {
this.image2 = {
image: "https://i.stack.imgur.com/zwwhZ.png"
};
}
}
<app-image-input-single (imageAdded)="imageAdd1($event)" (imageRemoved)="imageRemove1($event)" [image]="image1?.image">
</app-image-input-single>
<app-image-input-single (imageAdded)="imageAdd2($event)" (imageRemoved)="imageRemove2($event)" [image]="image2?.image">
</app-image-input-single>

问题

即使在与第二图像输入选择组件交互时,imageAdd2或imageRemove2也从未被触发。imageAdd1和imageRemove1总是在从1或2中添加或删除图像时触发。

我已经处理了好几天了,但我所尝试的都没有奏效,非常感谢任何帮助。

原因

  • ImageInputSingleComponent可能共享导致此问题的Ng2ImgMaxService的同一实例
  • 第二个问题是id=imageInput。这是用html硬编码的,但是它对于Component的每个实例都必须是唯一的

修复

只需提供Ng2ImgMaxServiceImageInputSingleComponent级别,以确保每个组件都有自己的副本。

@Component({
selector: "app-image-input-single",
templateUrl: "./image-input-single.component.html",
styleUrls: ["./image-input-single.component.scss"],
providers : [Ng2ImgMaxService] //<-- Ng2ImgMaxService is added in provider list
})
export class ImageInputSingleComponent implements OnInit {
}

最新更新