首页 > 解决方案 > 一个父级中有两个相同的组件,第一个覆盖第二个

问题描述

我有一个包含两个子组件的组件,子组件是相同的:

<!-- Some code ... -->

<app-upload-button
  #idBook
  [accept]="'image/*'"
  (loadend)="onImageLoaded('#this-idbook-preview')"
>
</app-upload-button>

<!-- Some code ... -->

<app-upload-button
  #userIdBook
  [accept]="'image/*'"
  (loadend)="onImageLoaded('#this-user-idbook-preview')"
>
</app-upload-button>

<!-- Some code ... -->

正如我们所见,这两个元素具有不同的引用#idBookand #userIdBook,并且函数中传递的字符串onImageLoaded也不同'#this-idbook-preview'and '#this-user-idbook-preview'

我的问题是,无论我是否与#idBookor交互#userIdBook,似乎#idBook总是在替换其他元素。当我在 中测试字符串时onImageLoaded,我总是得到'#this-idbook-preview',即使我点击了第二个元素。此外,只有第一个元素的变量被修改,第二个元素始终不变。

这里有什么问题?以及如何解决?

编辑:UploadButtonComponent 代码

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-upload-button',
  templateUrl: './upload-button.component.html',
  styleUrls: ['./upload-button.component.css']
})
export class UploadButtonComponent implements OnInit {
  @Input() accept: string;
  @Output() loadend: EventEmitter<void>;

  file: File;
  fileData: string;

  constructor() {
    this.loadend = new EventEmitter();
  }

  ngOnInit() {
    if (this.accept === undefined) {
      this.accept = '*';
    }
  }

  readFile(): void {
    const reader = new FileReader();

    reader.onloadend = (event: any) => {
      this.fileData = event.target.result;
      this.loadend.emit();
    };

    reader.readAsDataURL(this.file);
  }

  onChange(event: any): void {
    this.file = event.target.files[0];
    this.readFile();
  }
}

编辑2:迷你项目

我创建了一个迷你项目来显示问题,链接在这里https://drive.google.com/open?id=1yafbuiKYUQ-POeNAXHu0ATyo8l84ydCE

标签: angular

解决方案


使用 Angular,您必须小心原生 HTML 规则。其中之一是您不能有多个具有相同 ID 的元素。在这里,您在组件内部使用了一个常量 id,因此当您使用此 id 时,它们都会触发第一个组件(其中包含具有此 id 的页面的第一个元素)。
所以你有2个解决方案。

  1. 调用上传按钮的组件给了他一个唯一的 id。如果您忘记每个 id 都必须是唯一的,这可能会很危险。
  2. 做一些事情来确保同一个 id 永远不会被使用两次,使用计数器

你可以这样做:

// component
export class UploadButtonComponent implements OnInit {
  static nextIdNumber: number = 0; // will increment for each generated component
  public myId: string; // generated unique HTML id
  // ...

  constructor() {
    // ...
    this.myId = `this-files-${++UploadButtonComponent.nextIdNumber}`;
  }
  // ...
}

<!--HTML-->
<label
  [for]="myId"
  class="btn btn-primary"
>
  Upload
</label>

<input (change)="onChange($event)" [id]="myId" type="file" accept="{{ accept }}" capture>

推荐阅读