You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中如何为单个列表项显示文件上传错误提示

文件上传错误提示绑定到对应文件的解决方案

问题概述

我实现了一个文件上传界面,用户选择文件后会以列表形式展示。需求是:当文件过大或不符合类型要求时,对应文件项显示浅红色并附带错误提示。但当前的验证代码会把所有错误提示显示在每一个文件项上,哪怕只有部分文件存在问题。

原代码

TypeScript 文件

public validationError: { messages: string[] } = null;
public validateFiles(attachedFiles: AttachedFile[]) {
    const extensions = this.accept && this.accept
      .split(',')
      .map(x => x.toLowerCase().trim())
      .filter(x => !!x);

    const maxSize = this.maxFileSizeMB * 1024 * 1024;
    const errors = attachedFiles.map(file => {
      if (extensions && !extensions.some(x => file.name.toLowerCase().endsWith(x))) {
        return `File Type is not accepted`;
      }
      if (file.size > maxSize) {
        return `Exceeds maximum file size of ${this.maxFileSizeMB}MB.`
      }
      return null;
    }).filter(x => !!x);

    if (errors.length) {
      return {
        messages: errors
      };
    }

    return null;
}

HTML 文件

<ul *ngIf="attachedFiles && validationError" class="title-attached-files__list-with-errors">
    <li *ngFor="let file of attachedFiles; let i = index" class="c-file-with-errors" >
        <ng-container *ngIf="validationError">
            <span class="c-title-attached-files__validation-error" *ngFor="let message of validationError.messages">
                {{ message }}
            </span>
        </ng-container>
        <mat-icon class="c-file__icon" color="primary">upload_file</mat-icon>
        <span class="c-file__name">{{file.name}}</span>
        <span class="c-file__size">{{file.size | fileSize }}</span>
        <span *ngFor="let message of validationError.messages">
            {{ message }}
        </span>
        <button *ngIf='!readonly' class="c-file__delete" type="button"
            (click)="removeFile(i)"
            mat-icon-button color="primary"
            aria-label="Delete Added File">
                <mat-icon>close</mat-icon>
        </button>
    </li>
</ul>

解决方案

核心思路是给每个文件单独存储对应的错误信息,而不是把所有错误合并成一个数组。

1. 修改 TypeScript 代码

把全局的单个错误对象改成数组,每个元素对应一个文件的错误列表:

// 改为数组,索引与attachedFiles的文件一一对应
public validationError: { messages: string[] }[] = [];

public validateFiles(attachedFiles: AttachedFile[]) {
    const extensions = this.accept && this.accept
      .split(',')
      .map(x => x.toLowerCase().trim())
      .filter(x => !!x);

    const maxSize = this.maxFileSizeMB * 1024 * 1024;
    
    // 遍历每个文件,生成对应的错误信息
    this.validationError = attachedFiles.map(file => {
      const fileErrors: string[] = [];
      // 类型验证
      if (extensions && !extensions.some(x => file.name.toLowerCase().endsWith(x))) {
        fileErrors.push(`文件类型不被允许`);
      }
      // 大小验证
      if (file.size > maxSize) {
        fileErrors.push(`文件大小超过限制:${this.maxFileSizeMB}MB`);
      }
      return { messages: fileErrors };
    });

    // 可选:返回是否存在错误(用于后续逻辑判断)
    return this.validationError.some(item => item.messages.length > 0);
}

2. 修改 HTML 代码

根据文件索引获取对应错误,仅给有错误的文件应用样式,并只显示当前文件的错误:

<ul *ngIf="attachedFiles" class="title-attached-files__list-with-errors">
    <li *ngFor="let file of attachedFiles; let i = index" 
        <!-- 仅当当前文件有错误时,应用错误样式 -->
        [class.c-file-with-errors]="validationError[i]?.messages.length > 0">
        
        <mat-icon class="c-file__icon" color="primary">upload_file</mat-icon>
        <span class="c-file__name">{{file.name}}</span>
        <span class="c-file__size">{{file.size | fileSize }}</span>
        
        <!-- 只渲染当前文件对应的错误提示 -->
        <span *ngFor="let message of validationError[i]?.messages" 
              class="c-title-attached-files__validation-error">
            {{ message }}
        </span>

        <button *ngIf='!readonly' class="c-file__delete" type="button"
            (click)="removeFile(i)"
            mat-icon-button color="primary"
            aria-label="Delete Added File">
                <mat-icon>close</mat-icon>
        </button>
    </li>
</ul>

说明

  • 修改后,validationError数组的每个元素与attachedFiles中的文件一一对应,确保错误信息只绑定到对应的文件项。
  • 通过[class.c-file-with-errors]的条件绑定,只有存在错误的文件才会显示浅红色样式。
  • 错误提示部分仅遍历当前文件的错误列表,避免所有错误在每个文件上重复显示。

内容的提问来源于stack exchange,提问作者user2832411

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 22:05:27