在 angular 中使用 elementRef 从子级到父级发出文件

emit file with elementRef from child to parent in angular

提问人:mgh 提问时间:9/13/2023 最后编辑:mgh 更新时间:9/13/2023 访问量:37

问:

我正在尝试创建一个用户选择文件的组件,然后引用父组件传递文件,然后上传文件。为此,我创建了一个如下所示的组件:

import {Component, ElementRef, ViewChild} from '@angular/core';

@Component({
  selector: 'app-matching-upload-file',
  templateUrl: './matching-upload-file.component.html',
  styleUrls: ['./matching-upload-file.component.scss']
})
export class MatchingUploadFileComponent {

  @ViewChild('fileUpload') fileUpload: ElementRef;
  @Output() selectedFile = new EventEmitter<File[]>();

  constructor() {
  }

  onClick() {
    if (this.fileUpload) {
      this.fileUpload.nativeElement.click();
    }
  }

  onFileSelected(event) {
    const files = event.dataTransfer ? event.dataTransfer.files : event.target.files;

    this.onClick();

    // Then upload file and is successful

    // But when I pass to parent component and upload, file of formData is empty.
    
    this.selectedFile.emit(files);

  }

}
<button mat-raised-button color="primary"
        (click)="fileUpload.click()">
  <mat-icon>add</mat-icon>
  label
</button>
<input #fileUpload
       id="fileUpload"
       hidden
       type="file"
       (change)="onFileSelected($event)"
>

现在我想将上面的代码转换为一个组件并在另一个组件中使用它,当用户选择文件时,选定的文件作为输出传递给父组件,然后从父组件上传。为此,我更改如下:

首先将输出添加到子组件:

  @Output() selectedFile = new EventEmitter<File[]>();

但是当我将文件传递给父级时,文件的引用不存在,并且请求文件为空:

upload(file: File, url: string, token: string) {
    const formData: FormData = new FormData();
    formData.append('file', file, file.name);
    const headers = new HttpHeaders().set('Authorization', token);
    headers.append('Content-Type', 'multipart/form-data');
    const req = new HttpRequest(
      'POST',
      url,
      formData,
      {reportProgress: true, headers}
    );

    this.httpClient.request(req).subscribe(
      (response) => {
      },
      (error: HttpErrorResponse) => {
      });
  }

父组件

@Component({
  selector: 'app-matching',
  templateUrl: './matching.component.html',
  styleUrls: ['./matching.component.scss']
})
export class MatchingComponent implements OnInit {

  constructor(
    private uploadFileService: UploadFileService,
  ) {
  }

  ngOnInit() {
  }

  recieveFiles(files: File[]) {
    // Upload files[0]
    this.uploadFileService.upload(files[0], 'url', 'token');
    // But file in formData is empty.
  }

}
<app-matching-upload-file (selectedFile)="recieveFiles($event)"></app-matching-upload-file>

我正在尝试其他一些解决方案,例如:从父级初始化 ElementRef 并作为输入传递给子级或将 ElementRef 从子级传递给父级;但这些变化都没有奏效。如何将带有引用的文件从子项传递到父项?

角度 圆顶

评论

2赞 Random 9/13/2023
你能展示你父母的HTML代码吗?你如何触发该方法?你怎么听?upload@Output selectedFile
0赞 mgh 9/13/2023
我添加了父代码 ts 和 html。@Random
0赞 Random 9/13/2023
对我来说似乎还可以:(您可能需要添加日志(或在 chrome devtools 中调试它)才能跟踪您的文件,并查看它何时包含某些内容,以及何时丢失数据......
0赞 mgh 9/13/2023
我注意到一些事情,如果我在父组件中实现上传功能,一切都很好并成功上传文件,但是当我将文件传递给 UploadFileService 时,文件没有附加到 dataForm 上,@Random

答: 暂无答案