一个组件的Angular Event发射器与另一个组件混淆

时间:2018-10-28 15:49:30

标签: javascript html angular typescript

背景

我有两个图像输入组件和一个测试容器组件。 image-input-single是一个“哑巴”组件,可简化选择图像,获取压缩文件及其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>

然后我有一个简单的组件,其中包含两个image-input-single实例

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。在1或2中添加或删除图像时,总是会触发imageAdd1和imageRemove1。

经过数天的处理,但我尝试过的所有方法均无济于事,将不胜感激。

1 个答案:

答案 0 :(得分:1)

  

原因

  • 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 {

}