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

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

Angular Table Content Not Displaying Properl API

问题

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

  1. <div class="card">
  2. <hr>
  3. <div class="card-header">
  4. <h2>Bank Statements of {{this.selectedOptionProduct}}</h2>
  5. </div>
  6. <div class="card-body">
  7. <div class="loading-spinner" *ngIf="productSelectedForLoading && loading">
  8. <div class="spinner"></div>
  9. </div>
  10. <table class="table">
  11. <thead>
  12. <tr>
  13. <th>Product Name</th>
  14. <th>File Uploads</th>
  15. <th>Status</th>
  16. <th>File Extension</th>
  17. </tr>
  18. </thead>
  19. <tbody>
  20. <tr *ngFor="let row of tableData">
  21. <td>{{ row.file_type_id }}</td>
  22. <td>
  23. <input type="file" #fileInput [value]="row.file_type_id" (change)="onFileSelected($event, row)">
  24. <button (click)="uploadFile(row)">Upload</button>
  25. <button (click)="resetFileInput(fileInput)">Reset</button>
  26. </td>
  27. <td>{{ row.status }}</td>
  28. <td>
  29. <select (change)="onOptionSelectedExtention($event.target)">
  30. <option>Select one</option>
  31. <option *ngFor="let extention of row.file_extensions" mat-menu-item [value]="extention">{{extention}}</option>
  32. </select>
  33. </td>
  34. </tr>
  35. </tbody>
  36. </table>
  37. </div>
  38. </div>

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

  1. tableData: any[] = [];
  2. selectedExtention: String;
  3. loading: boolean = true;
  4. async getTableData(selectedProduct: any) {
  5. try {
  6. const url = `API?product_id=${selectedProduct}`;
  7. const response = await axios.get(url);
  8. const data = response.data;
  9. this.tableData = data;
  10. this.loading = false;
  11. console.log(this.tableData);
  12. } catch (error) {
  13. console.error('Error:', error);
  14. }
  15. }
  16. resetFileInput(fileInput: HTMLInputElement) {
  17. fileInput.value = ''; // 重置文件输入字段的值
  18. }
  19. onFileSelected(event: any, row: any) {
  20. row.selectedFile = event.target.files[0];
  21. console.log(row.selectedFile['name']);
  22. }
  23. uploadFile(row: any) {
  24. const file = row.selectedFile;
  25. console.log(file);
  26. if (file) {
  27. const formData = new FormData();
  28. formData.append('file', file);
  29. // 发送HTTP请求上传文件
  30. this.http.post('your-upload-api-url', formData)
  31. .subscribe(
  32. response => {
  33. // 处理成功响应,例如更新状态
  34. row.status = 'Uploaded';
  35. },
  36. error => {
  37. // 处理错误响应,例如显示错误消息
  38. console.log("hello");
  39. }
  40. );
  41. }
  42. }
  43. onOptionSelectedExtention(selectedOption: any) {
  44. this.selectedExtention = selectedOption.value;
  45. console.log(this.selectedExtention);
  46. }

希望这对你有所帮助。

英文:

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

  1. &lt;div class=&quot;card&quot; &gt;
  2. &lt;hr&gt;
  3. &lt;div class=&quot;card-header&quot;&gt;
  4. &lt;h2&gt;Bank Statements of {{this.selectedOptionProduct}}&lt;/h2&gt;
  5. &lt;/div&gt;
  6. &lt;div class=&quot;card-body&quot;&gt;
  7. &lt;div class=&quot;loading-spinner&quot; *ngIf=&quot;productSelectedForLoading &amp;&amp; loading&quot;&gt;
  8. &lt;div class=&quot;spinner&quot;&gt;&lt;/div&gt;
  9. &lt;/div&gt;
  10. &lt;table class=&quot;table&quot; &gt;
  11. &lt;thead&gt;
  12. &lt;tr&gt;
  13. &lt;th&gt;Product Name&lt;/th&gt;
  14. &lt;th&gt;File Uploads&lt;/th&gt;
  15. &lt;th&gt;Status&lt;/th&gt;
  16. &lt;th&gt; File extenstion &lt;/th&gt;
  17. &lt;/tr&gt;
  18. &lt;/thead&gt;
  19. &lt;tbody&gt;
  20. &lt;tr *ngFor=&quot;let row of tableData &quot; &gt;
  21. &lt;td&gt;{{ row.file_type_id }}&lt;/td&gt;
  22. &lt;td&gt;
  23. &lt;input type=&quot;file&quot; #fileInput [value]=&quot;row.file_type_id&quot; (change)=&quot;onFileSelected($event, row)&quot;&gt;
  24. &lt;button (click)=&quot;uploadFile(row)&quot;&gt;Upload&lt;/button&gt;
  25. &lt;button (click)=&quot;resetFileInput(fileInput)&quot;&gt;Reset&lt;/button&gt;
  26. &lt;/td&gt;
  27. &lt;td&gt;{{ row.status }}&lt;/td&gt;
  28. &lt;td&gt;
  29. &lt;select (change)=&quot;onOptionSelectedExtention($event.target)&quot; &gt;
  30. &lt;option&gt;Select one &lt;/option&gt;
  31. &lt;option *ngFor=&quot;let extention of row.file_extensions&quot; mat-menu-item [value]=&quot;extention&quot; &gt;{{extention}}&lt;/option&gt;
  32. &lt;/select&gt;
  33. &lt;/td&gt;
  34. &lt;/tr&gt;
  35. &lt;/tbody&gt;
  36. &lt;/table&gt;

This is my component.ts file for those functions

  1. tableData: any[] = [
  2. ];
  3. selectedExtention : String
  4. loading: boolean = true;
  5. onOptionSelectedExtention(selectedOption : any){
  6. this.selectedExtention=selectedOption.value
  7. console.log(this.selectedExtention)
  8. }
  9. async getTableData(selectedProduct: any) {
  10. try {
  11. const url = `API?product_id=${selectedProduct}`;
  12. const response = await axios.get(url);
  13. const data = response.data;
  14. this.tableData = data;
  15. this.loading = false;
  16. console.log(this.tableData);
  17. // Flatten the tableData array
  18. this.flattenedTableData = this.tableData.reduce((accumulator, row) =&gt; {
  19. return accumulator.concat(row.items);
  20. }, []);
  21. console.log(this.flattenedTableData);
  22. // Use the variable as needed
  23. console.log(data);
  24. } catch (error) {
  25. // Handle any errors
  26. console.error(&#39;Error:&#39;, error);
  27. }
  28. }
  29. resetFileInput(fileInput: HTMLInputElement) {
  30. fileInput.value = &#39;&#39;; // Reset the value of the file input field
  31. }
  32. onFileSelected(event: any, row: any) {
  33. row.selectedFile = event.target.files[0];
  34. console.log(row.selectedFile[&#39;name&#39;])
  35. }
  36. uploadFile(row: any) {
  37. const file = row.selectedFile;
  38. console.log(file);
  39. if (file) {
  40. const formData = new FormData();
  41. formData.append(&#39;file&#39;, file);
  42. // Make an HTTP request to upload the file
  43. this.http.post(&#39;your-upload-api-url&#39;, formData)
  44. .subscribe(
  45. response =&gt; {
  46. // Handle success response, e.g., update status
  47. row.status = &#39;Uploaded&#39;;
  48. },
  49. error =&gt; {
  50. // Handle error response, e.g., display an error message
  51. console.log(&quot;hello&quot;)
  52. }
  53. );
  54. }
  55. }

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] 属性上的括号来解决这个问题。这将分配一个字符串值,而不是绑定属性。

例如:

  1. <td>
  2. <input type="file" #fileInput value="row.file_type_id" (change)="onFileSelected($event, row)">
  3. <button (click)="uploadFile(row)">Upload</button>
  4. <button (click)="resetFileInput(fileInput)">Reset</button>
  5. </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.

  1. &lt;td&gt;
  2. &lt;input type=&quot;file&quot; #fileInput value=&quot;row.file_type_id&quot; (change)=&quot;onFileSelected($event, row)&quot;&gt;
  3. &lt;button (click)=&quot;uploadFile(row)&quot;&gt;Upload&lt;/button&gt;
  4. &lt;button (click)=&quot;resetFileInput(fileInput)&quot;&gt;Reset&lt;/button&gt;
  5. &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:

确定