Angular表格内容未正确显示API。

huangapple go评论72阅读模式
英文:

Angular Table Content Not Displaying Properl API

问题

The API返回一个对象数组,我可以提取并循环遍历它,然后将其转化为行。但问题是,它只在一行中显示一个元素,并生成两个Rows的条目。但是,当我点击选择文件选项(有一个我们可以选择文件的列)并提供文件路径时,另一行的数据也会显示,还有一个文件扩展名列,它是一个下拉列表,数据也来自API。当我向文件添加路径时,这个功能可以正常工作。我认为这里存在一些渲染问题。这是我的HTML表格代码:

<div class="card">
  <hr>
  <div class="card-header">
    <h2>Bank Statements of {{this.selectedOptionProduct}}</h2>
  </div>
  <div class="card-body">
    <div class="loading-spinner" *ngIf="productSelectedForLoading && loading">
      <div class="spinner"></div>
    </div>
    <table class="table">
      <thead>
        <tr>
          <th>Product Name</th>
          <th>File Uploads</th>
          <th>Status</th>
          <th>File Extension</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let row of tableData">
          <td>{{ row.file_type_id }}</td>
          <td>
            <input type="file" #fileInput [value]="row.file_type_id" (change)="onFileSelected($event, row)">
            <button (click)="uploadFile(row)">Upload</button>
            <button (click)="resetFileInput(fileInput)">Reset</button>
          </td>
          <td>{{ row.status }}</td>
          <td>
            <select (change)="onOptionSelectedExtention($event.target)">
              <option>Select one</option>
              <option *ngFor="let extention of row.file_extensions" mat-menu-item [value]="extention">{{extention}}</option>
            </select>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

这是我的组件.ts文件中的函数部分:

tableData: any[] = [];
selectedExtention: String;
loading: boolean = true;

async getTableData(selectedProduct: any) {
  try {
    const url = `API?product_id=${selectedProduct}`;
    const response = await axios.get(url);
    const data = response.data;
    this.tableData = data;
    this.loading = false;
    console.log(this.tableData);
  } catch (error) {
    console.error('Error:', error);
  }
}

resetFileInput(fileInput: HTMLInputElement) {
  fileInput.value = ''; // 重置文件输入字段的值
}

onFileSelected(event: any, row: any) {
  row.selectedFile = event.target.files[0];
  console.log(row.selectedFile['name']);
}

uploadFile(row: any) {
  const file = row.selectedFile;
  console.log(file);
  if (file) {
    const formData = new FormData();
    formData.append('file', file);

    // 发送HTTP请求上传文件
    this.http.post('your-upload-api-url', formData)
      .subscribe(
        response => {
          // 处理成功响应,例如更新状态
          row.status = 'Uploaded';
        },
        error => {
          // 处理错误响应,例如显示错误消息
          console.log("hello");
        }
      );
  }
}

onOptionSelectedExtention(selectedOption: any) {
  this.selectedExtention = selectedOption.value;
  console.log(this.selectedExtention);
}

希望这对你有所帮助。

英文:

The API Returns an array of objects so that i could extract it and loop it through and make ROWS out of it . but the problem is it displays only one element in the row and makes 2 entries of Rows . but When i click on the choose files options (there is a column in which we can choose files) and give a file path . the data of the other row displays also there is a file extension column which is a drop down . the data from this drop down also comes from an API .this functionality works when i add a path to the file . i think there is some rendering issue . This is my HTML code for the table

&lt;div class=&quot;card&quot; &gt;
&lt;hr&gt;
&lt;div class=&quot;card-header&quot;&gt;
&lt;h2&gt;Bank Statements of {{this.selectedOptionProduct}}&lt;/h2&gt;
&lt;/div&gt;
&lt;div class=&quot;card-body&quot;&gt;
&lt;div class=&quot;loading-spinner&quot; *ngIf=&quot;productSelectedForLoading &amp;&amp; loading&quot;&gt;
&lt;div class=&quot;spinner&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;table class=&quot;table&quot; &gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Product Name&lt;/th&gt;
&lt;th&gt;File Uploads&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt; File extenstion &lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr *ngFor=&quot;let row of tableData &quot; &gt;
&lt;td&gt;{{ row.file_type_id }}&lt;/td&gt;
&lt;td&gt;
&lt;input type=&quot;file&quot;  #fileInput [value]=&quot;row.file_type_id&quot; (change)=&quot;onFileSelected($event, row)&quot;&gt;
&lt;button (click)=&quot;uploadFile(row)&quot;&gt;Upload&lt;/button&gt;
&lt;button (click)=&quot;resetFileInput(fileInput)&quot;&gt;Reset&lt;/button&gt;
&lt;/td&gt;
&lt;td&gt;{{ row.status }}&lt;/td&gt;
&lt;td&gt;
&lt;select (change)=&quot;onOptionSelectedExtention($event.target)&quot; &gt;
&lt;option&gt;Select one &lt;/option&gt;
&lt;option *ngFor=&quot;let extention of row.file_extensions&quot; mat-menu-item [value]=&quot;extention&quot; &gt;{{extention}}&lt;/option&gt;
&lt;/select&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

This is my component.ts file for those functions

tableData: any[] = [ 
];
selectedExtention : String
loading: boolean = true;
onOptionSelectedExtention(selectedOption : any){
this.selectedExtention=selectedOption.value
console.log(this.selectedExtention)
}
async getTableData(selectedProduct: any) {
try {
const url = `API?product_id=${selectedProduct}`;
const response = await axios.get(url);
const data = response.data;
this.tableData = data;
this.loading = false;
console.log(this.tableData);
// Flatten the tableData array
this.flattenedTableData = this.tableData.reduce((accumulator, row) =&gt; {
return accumulator.concat(row.items);
}, []);
console.log(this.flattenedTableData);
// Use the variable as needed
console.log(data);
} catch (error) {
// Handle any errors
console.error(&#39;Error:&#39;, error);
}
}
resetFileInput(fileInput: HTMLInputElement) {
fileInput.value = &#39;&#39;; // Reset the value of the file input field
}
onFileSelected(event: any, row: any) {
row.selectedFile = event.target.files[0];
console.log(row.selectedFile[&#39;name&#39;])
}
uploadFile(row: any) {
const file = row.selectedFile;
console.log(file);
if (file) {
const formData = new FormData();
formData.append(&#39;file&#39;, file);
// Make an HTTP request to upload the file
this.http.post(&#39;your-upload-api-url&#39;, formData)
.subscribe(
response =&gt; {
// Handle success response, e.g., update status
row.status = &#39;Uploaded&#39;;
},
error =&gt; {
// Handle error response, e.g., display an error message
console.log(&quot;hello&quot;)
}
);
}
}

And this only happens when i have two objects in that array from the API . how to fix it . here are some of the SS for visual representation. This picture is when i don't hit choose the file option as you could see this does not render the second row items neither the file extension Angular表格内容未正确显示API。

edit :

This is after hitting choose files and it re rendered Angular表格内容未正确显示API。

The API response for the table
Angular表格内容未正确显示API。

The updated image when i choose the file path
Angular表格内容未正确显示API。

答案1

得分: 0

问题在于您使用属性绑定而不是将字符串值直接分配给输入。因此,第一行正确渲染,但当渲染第二行时,会发生冲突,因为该属性已经绑定到第一行的输入。这导致以下 DOM 异常:

"ERROR DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string."

您可以通过简单地删除 [value] 属性上的括号来解决这个问题。这将分配一个字符串值,而不是绑定属性。

例如:

<td>
    <input type="file" #fileInput value="row.file_type_id" (change)="onFileSelected($event, row)">
    <button (click)="uploadFile(row)">Upload</button>
    <button (click)="resetFileInput(fileInput)">Reset</button>
</td>
英文:

The problem is that you are using property binding rather than just assigning a a string value to your input. Therefor, the first row renders correctly, but when the second row is rendered, there is a conflict as the property is already bound to the first row's input. This results in the following DOM exception:

"ERROR DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string."

You can resolve this by simply removing brackets on your [value] property. This will assign a string value rather that binding the property.

Ex.

         &lt;td&gt;
&lt;input type=&quot;file&quot;  #fileInput value=&quot;row.file_type_id&quot; (change)=&quot;onFileSelected($event, row)&quot;&gt;
&lt;button (click)=&quot;uploadFile(row)&quot;&gt;Upload&lt;/button&gt;
&lt;button (click)=&quot;resetFileInput(fileInput)&quot;&gt;Reset&lt;/button&gt;
&lt;/td&gt;

huangapple
  • 本文由 发表于 2023年5月17日 12:43:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76268619.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定