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

Angular2:多文件上传二进制内容绑定到结构化对象数组的疑问

Hi DarioN1! Let's work through this multi-file upload scenario in Angular where you need to bind each selected file's binary content to your PriceList array items. I'll walk you through a complete implementation tailored to your existing setup:

First, update your component template to render a file input for each item in your listFile array. We'll use *ngFor to loop through the array and attach a change event handler that passes both the file event and the corresponding PriceList item:

<div class="price-list-item" *ngFor="let priceList of listFile; let idx = index">
  <h4>Price List #{{idx + 1}}</h4>
  <div>
    <label>Code: {{priceList.code}}</label>
  </div>
  <div>
    <label>Name: {{priceList.name}}</label>
  </div>
  <div>
    <label>Select File:</label>
    <input 
      type="file" 
      (change)="handleFileSelection($event, priceList)"
      accept=".pdf,.xlsx,.csv" <!-- Optional: Restrict file types -->
    >
  </div>
  <hr>
</div>

<button (click)="uploadAllPriceLists()" [disabled]="listFile.some(item => !item.binary)">
  Upload All Price Lists
</button>

2. Implement File Reading Logic in the Component

Next, add the handleFileSelection method to your component. This method will use the FileReader API to read the selected file's content and assign it to the binary property of the target PriceList item. We'll cover two common scenarios depending on how your WebAPI accepts binary data:

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { PriceList } from './path-to-your-price-list-model';

@Component({
  selector: 'app-price-list-upload',
  templateUrl: './price-list-upload.component.html'
})
export class PriceListUploadComponent {
  public listFile: PriceList[] = [];

  constructor(private http: HttpClient) {
    // Assume this is populated from your WebAPI as you mentioned
    // this.listFile = fetchedPriceLists;
  }

  handleFileSelection(event: Event, priceList: PriceList): void {
    const fileInput = event.target as HTMLInputElement;
    const selectedFile = fileInput.files?.[0];

    if (!selectedFile) return;

    const reader = new FileReader();

    // Option 1: Convert file to Base64 string (ideal for JSON payloads)
    reader.readAsDataURL(selectedFile);
    reader.onload = () => {
      // Strip the "data:[mime-type];base64," prefix if your backend expects raw Base64
      const base64Content = reader.result?.toString().split(',')[1];
      priceList.binary = base64Content;
    };

    // Option 2: Keep file as Blob (ideal for FormData uploads)
    // reader.readAsArrayBuffer(selectedFile);
    // reader.onload = () => {
    //   priceList.binary = new Blob([reader.result as ArrayBuffer], { type: selectedFile.type });
    // };

    reader.onerror = (error) => {
      console.error(`Failed to read file ${selectedFile.name}:`, error);
    };
  }

  uploadAllPriceLists(): void {
    // Choose the upload method based on your WebAPI's requirements

    // Method 1: Send as JSON (use with Option 1 above)
    this.http.post('/api/price-lists/bulk-upload', this.listFile)
      .subscribe({
        next: (response) => {
          console.log('Upload successful!', response);
          // Reset file inputs or array here if needed
        },
        error: (err) => console.error('Upload failed:', err)
      });

    // Method 2: Send as FormData (use with Option 2 above)
    // const formData = new FormData();
    // this.listFile.forEach((item, index) => {
    //   formData.append(`priceLists[${index}].idPriceList`, item.idPriceList.toString());
    //   formData.append(`priceLists[${index}].code`, item.code);
    //   formData.append(`priceLists[${index}].name`, item.name);
    //   formData.append(
    //     `priceLists[${index}].binary`, 
    //     item.binary, 
    //     `${item.code}-${item.name}.${selectedFile.name.split('.').pop()}`
    //   );
    // });
    // this.http.post('/api/price-lists/bulk-upload', formData)
    //   .subscribe(...);
  }
}

3. Key Notes for Your Implementation

  • Async File Reading: Remember that FileReader works asynchronously, so always assign the binary value inside the onload callback (never immediately after calling readAsDataURL or readAsArrayBuffer).
  • Backend Compatibility: Check your WebAPI's documentation to confirm whether it accepts Base64 strings in JSON or expects multipart FormData. Adjust the file reading and upload logic accordingly.
  • Validation: You can add checks in handleFileSelection to validate file size, type, or extension before reading the file (e.g., if (selectedFile.size > 5 * 1024 * 1024) { alert('File too large!'); return; }).
  • Disabled Upload Button: The button in the template is disabled if any PriceList item doesn't have a binary value, ensuring you don't upload incomplete data.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:01:14