取消文件选择器会导致步进器对话框关闭

问题描述 投票:0回答:1

我正在开发一个 Angular Web 应用程序,它通过 Nebular Stepper 组件收集数据。其中一个步骤允许用户使用包含 type="file" 输入的另一个组件附加图像或文档。附加图像按预期工作,但如果取消文件选择器,底层步进器对话框也会关闭并且数据会丢失。我是否正确地假设这是由关闭文件选择器时触发取消事件引起的?有没有办法阻止该事件到达对话框?

目前,如果我附加通用附件然后将其删除,取消文件选择器不会关闭步进器组件。

我想阻止这种行为,但不确定如何实现。我尝试停止事件传播,但所有尝试都失败了。

stepper.component.ts

    /**
   * Handler for the selectedFilesChanged event of mat-file-upload component
   * for Attachments.
   * @param {FileList} fileList List of File objects of the loaded files.
   */
  onSelectedAttachmentsChanged(fileList: FileList): void {
    // White list for attachments - just PDF for now.
    if (fileList.item(0).type == "application/pdf") {
      getBase64EncodedFromFile(fileList.item(0)).subscribe({
        next: (result: string) => {
          const newAttachment: Attachment = {
            filename: fileList.item(0).name,
            fileExtension: FileExtension.pdf,
            data: result,
            mimeType: fileList.item(0).type,
          };

          this.changeRequest.attachments = [
            ...this.changeRequest.attachments,
            newAttachment,
          ];
        },
        error: (err: Error) => {
          console.log("An error has occurred: ", err);
        },
      });
    } else {
      this._dialogService.open(ConfirmDialogComponent, {
        context: {
          confirmHeader: "Unsupported File Type",
          confirmMessage: "Only PDFs can be attached here.",
          confirmBtnText: "Ok",
          confirmBtnStatus: "basic",
          confirmStatus: "info",
          confirmShowCancelBtn: false,
        },
      });
    }
  }

stepper.component.html

<div fxLayout="row" fxLayoutAlign="center center" fxLayoutGap="1em">
          <mat-file-upload
            [acceptedTypes]="'.pdf'"
            [labelText]="''"
            [selectButtonText]="'Attach a PDF'"
            [showUploadButton]="false"
            [allowMultipleFiles]="false"
            (selectedFilesChanged)="onSelectedAttachmentsChanged($event)"
          ></mat-file-upload>
</div>

mat-file-upload.component.ts

    import {
  Component,
  ElementRef,
  EventEmitter,
  Input,
  Output,
  ViewChild,
} from "@angular/core";

@Component({
  selector: "mat-file-upload",
  template: `
    <!--<span class="file-input-text">{{ labelText }}</span>-->
    <button
      nbButton
      [type]="selectFilesButtonType"
      [disabled]="disabled"
      color="primary"
      class="file-input-button"
      (click)="fileInput.click()"
      [attr.aria-label]="selectButtonText"
    >
      <nb-icon icon="plus-outline"></nb-icon>
      <span>{{ selectButtonText }}</span>
      <input
        #fileInput
        type="file"
        style="display: none"
        [accept]="acceptedTypes"
        [multiple]="allowMultipleFiles"
        (change)="filesChanged($event.target.files)"
      />
    </button>
    <button
      mat-raised-button
      [type]="uploadButtonType"
      color="primary"
      class="file-input-button"
      [disabled]="!selectedFiles || disabled"
      (click)="uploadFiles()"
      *ngIf="showUploadButton"
      [attr.aria-label]="uploadButtonText"
    >
      {{ uploadButtonText }}
    </button>
    <!--<span class="file-input-text">{{ selectedFileText }}</span>-->
    <!--<button
      mat-icon-button
      (click)="filesChanged(null)"
      type="button"
      aria-label="Remove Selected File(s)"
      *ngIf="selectedFiles != null && selectedFiles.length > 0"
    >
      <mat-icon *ngIf="!customSvgIcon">close</mat-icon>
      <mat-icon *ngIf="customSvgIcon" [svgIcon]="customSvgIcon"></mat-icon>
    </button>-->
  `,
  styles: [
    ".file-input-button { margin-right: 8px !important }",
    // eslint-disable-next-line max-len
    ".file-input-text { font-size: 14px !important; margin-right: 8px !important }",
  ],
})
export class MatFileUploadComponent {
  @Input() labelText = "Select File(s)";
  @Input() selectButtonText = "Select File(s)";
  @Input() selectFilesButtonType: "button" | "menu" | "reset" | "submit" =
    "button";
  @Input() uploadButtonText = "Upload File(s)";
  @Input() uploadButtonType: "button" | "menu" | "reset" | "submit" = "button";
  @Input() allowMultipleFiles = false;
  @Input() showUploadButton = true;
  @Input() acceptedTypes = "*.*";
  @Input() customSvgIcon?: string = null;
  @Input() disabled = false;
  @Output() uploadClicked: EventEmitter<FileList> = new EventEmitter<
    FileList
  >();
  @Output() selectedFilesChanged: EventEmitter<FileList> = new EventEmitter<
    FileList
  >();

  @ViewChild("fileInput") fileInputRef: ElementRef;
  selectedFiles: FileList;
  selectedFileText = "";

  filesChanged(files?: FileList): void {
    this.selectedFiles = files;
    this.selectedFilesChanged.emit(this.selectedFiles);
    if (this.selectedFiles) {
      const numSelectedFiles = this.selectedFiles.length;
      this.selectedFileText =
        numSelectedFiles === 1
          ? this.selectedFiles[0].name
          : `${numSelectedFiles} files selected`;
    } else {
      this.selectedFileText = "";
      this.resetFileInput();
    }
  }

  uploadFiles(): void {
    this.uploadClicked.emit(this.selectedFiles);
    this.resetFileInput();
  }

  resetFileInput(): void {
    this.fileInputRef.nativeElement.value = "";
  }
}

我确认文件输入正在发出一个取消事件,该事件通过向其构造函数添加事件侦听器来到达我的步进器组件。有没有办法让步进器忽略该事件?

angular dialog angular-components filepicker nebular
1个回答
0
投票

我终于能够通过使用 @HostListener 侦听取消事件并停止其在我的上传组件上的传播来解决我的问题。

@HostListener('cancel', ['$event'])
  onCancel(event: Event){ 
    console.log('Cancel host listener.'); 
    event.stopImmediatePropagation(); 
  };
© www.soinside.com 2019 - 2024. All rights reserved.