[Angular] inputタグに指定したchangeイベントで再度同じファイルを選択してもイベントを検知する


inputタグにchangeイベントを指定し、ファイルの選択を検知してなにかするよくある処理です。
同じファイルを選択してもイベントの検知をしたい際の解決策となります。

同じファイルを選択してもイベント検知できない例

example.component.html
<input type="file" (change)="changeFile($event)" />
example.component.ts
export class ExampleComponent {
  changeFile($event: Readonly<Event>): void {
    // 処理
  }
}

ファイル選択ダイアログでファイルを選択した後、同じファイルを選択してもchangeイベントは検知できません。

解決策

example.component.html
<input #fileInput type="file" (change)="changeFile($event)" />
example.component.ts
export class ExampleComponent {
  @ViewChild('fileInput') fileInput: ElementRef;

  changeFile($event: Readonly<Event>): void {
    // 処理
    this.fileInput.nativeElement.value = '';
  }
}

ViewChildでrefを取得し、直接valueを初期化することでchangeイベントが同じファイルを選択されても検知できるようになります。