Angular文件上传点击无响应:未弹出确认弹窗问题求助
文件上传无响应排查方案
问题现象
上传界面正常显示,但点击上传按钮后无任何动作,预期弹出的“您确定吗?”确认窗口未出现。
Angular端代码检查
file-upload-component.ts
import { CommonModule } from '@angular/common'; import { HttpClientModule, HttpErrorResponse, HttpHeaders } from '@angular/common/http'; import { Component, Input } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { BrowserModule } from '@angular/platform-browser'; import { NgxFileDropEntry, FileSystemFileEntry, FileSystemDirectoryEntry, NgxFileDropModule } from 'ngx-file-drop'; import { HttpClientService } from '../http-client.service'; import { AlertifyService, MessagePosition, MessageType } from '../alertify.service'; import { MatDialog } from '@angular/material/dialog'; import { FileUplaodDialogState, FileUploadDialogComponent } from '../../../dialogs/file-upload-dialog/file-upload-dialog.component'; import { DialogService } from '../dialog.service'; import { MatButton } from '@angular/material/button'; @Component({ selector: 'app-file-upload', standalone: true, imports: [ CommonModule, FormsModule, NgxFileDropModule, MatButton ], templateUrl: './file-upload.component.html', styleUrl: './file-upload.component.scss' }) export class FileUploadComponent { constructor( private httpClient : HttpClientService, private alertift : AlertifyService, private dialog : MatDialog, private dialogService : DialogService ) { } @Input() options : Partial<FileUploadOptions>; public files: NgxFileDropEntry[]; public dropped(files: NgxFileDropEntry[]) { this.files = files; const formData = new FormData() for (const droppedFile of files) { (droppedFile.fileEntry as FileSystemFileEntry).file((file: File) => { formData.append(droppedFile.relativePath, file, droppedFile.relativePath) }) } this.dialogService.openDialog({ componentType : FileUploadDialogComponent, data : FileUplaodDialogState.Yes, afterClosed : () => { this.httpClient.post({ controller : this.options.controller, action : this.options.action, queryString : this.options.queryString, headers : new HttpHeaders({ "responseType" : "blob" }) },formData).subscribe(res => { this.alertift.message("Dosya veya dosyalar başarıyla yüklendi", { messagePosition : MessagePosition.TopRight, messageType : MessageType.Success }) },(errorResponse : HttpErrorResponse) => { this.alertift.message("Dosya veya dosyalar yüklenirken hata oluştu", { messagePosition : MessagePosition.TopRight, messageType : MessageType.Error }) }) } }) } } export class FileUploadOptions { controller? : string; action? : string; queryString? : string; acceptedFiles? : string; }
select-article-image-dialog.component.ts
import { Component, Inject, OnInit, Output } from '@angular/core'; import { BaseDialog } from '../base-dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { FileUplaodDialogState } from '../file-upload-dialog/file-upload-dialog.component'; import {MatDialogModule} from '@angular/material/dialog'; import { MatButton } from '@angular/material/button'; import { FileUploadComponent, FileUploadOptions } from '../../services/common/file-upload/file-upload.component'; @Component({ selector: 'app-select-article-image-dialog', standalone: true, imports: [ MatDialogModule, MatButton, FileUploadComponent ], templateUrl: './select-article-image-dialog.component.html', styleUrl: './select-article-image-dialog.component.scss' }) export class SelectArticleImageDialogComponent extends BaseDialog<SelectArticleImageDialogComponent> { constructor (dialogRef : MatDialogRef<SelectArticleImageDialogComponent>, @Inject(MAT_DIALOG_DATA) public data : SelectArticleImageState | string) { super(dialogRef) } @Output() options : Partial<FileUploadOptions> = { acceptedFiles : ".png,.jpg,.jpeg", action : "upload", controller : "articles", queryString :`id=${this.data}` } } export enum SelectArticleImageState { Close }
HTML模板
<h2 mat-dialog-title></h2> <mat-dialog-content class="mat-typography"> <app-file-upload [options]="options"></app-file-upload> </mat-dialog-content> <mat-dialog-actions align="end"> <button mat-button mat-dialog-close>Cancel</button> </mat-dialog-actions>
服务端代码
[HttpPost("[action]")] public async Task<IActionResult> Upload(string id) { List<(string fileName, string pathOrContainerName)> result = await _storageService.UploadAsync("images", Request.Form.Files, _webHostEnvironment); await _articleImageFileWriteRepository.AddRangeAsync(result.Select(x => new ArticleImageFile() { FileName = x.fileName, Path = x.pathOrContainerName, Storage = "Local", }).ToList()); await _articleImageFileWriteRepository.SaveAsync(); return Ok(); }
排查要点
- 修正属性装饰器错误:
SelectArticleImageDialogComponent中的options属性误用了@Output(),这会导致子组件app-file-upload无法正确接收配置参数,直接移除@Output()即可。 - 检查拼写错误:代码中
FileUplaodDialogState存在拼写错误(缺少字母n,应为FileUploadDialogState),如果FileUploadDialogComponent中定义的枚举是正确拼写,会导致弹窗无法正确识别状态,进而不触发弹窗。 - 异步操作顺序问题:
dropped方法中,formData的构建是在异步回调file()中完成的,此时调用dialogService.openDialog后,afterClosed回调执行时formData可能还未填充完成,需要将openDialog逻辑移到异步回调内部,或者使用Promise.all等待所有文件处理完成后再打开弹窗。 - 控制台报错检查:打开浏览器开发者工具的控制台,查看是否有组件未注册、依赖注入失败、模板绑定错误等信息,这些是最直接的问题线索。
- DialogService实现验证:确认
dialogService.openDialog方法是否正确调用了MatDialog.open()来打开FileUploadDialogComponent,并且该组件已正确导入到当前模块中。
内容的提问来源于stack exchange,提问作者İbrahim Özdemir
相关产品推荐
相关产品推荐

