有没有一种方法可以从一个对象数组中创建动态表格组来编辑Angular 11中动态表的表行?

发布于 2025-02-09 06:03:13 字数 2465 浏览 2 评论 0 原文

我想创建一个动态数据表,该表将从后端服务器接收数据。数据将作为对象数组。是否有一种方法可以从数据中动态创建/绑定表单组,该组将允许对表的每一行进行内联编辑并在编辑模式时更新更改。除非我必须这样做,否则我不想每次都为表格数据进行硬码数据。我也无法为该项目使用角材料。这是表行的组件。该表充当数据表,但我似乎无法弄清楚如何使其可编辑。

import {
  Component,
  Input,
  Output,
  EventEmitter,
  ViewChild,
  ChangeDetectionStrategy,
} from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';
import { EditButtonGroupComponent } from '../../edit-button-group/edit-button-group.component';

@Component({
  selector: '[dataTableRow]',
  templateUrl: './data-table-row-form.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DataTableRowFormComponent {
  @ViewChild('editButtonGroup', { static: true })
  editButtonGroup: EditButtonGroupComponent;
  @Input() data: any[];
  @Input() formModel: any;
  @Input() useEditButton: boolean;
  @Input() updating: boolean;
  @Input() deleting: boolean;
  @Input() index: number;
  
  checkMark(value: any) {
    if (value === true) {
      return 'bi bi-check-lg';
    } else {
      return '';
    }
  }

  booleanCheck(val: any) {
    if (typeof val === 'boolean') {
      return true;
    } else {
      return false;
    }
  }

  returnZero() {
    return 0;
  }

  enableEditMode() {
    this.editModeEnabled = true;
    this.copyModel();
  }

  disableEditMode() {
    this.editModeEnabled = false;
    this.copyModel();
  }
  
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.0/angular.min.js"></script>

<td *ngFor="let y of data[index] | keyvalue : returnZero">
  <i [ngClass]="checkMark(y.value)" *ngIf="booleanCheck(y.value) else default"></i>
  <ng-template #default>
    <ng-container *ngIf="!editModeEnabled else form">{{y.value}}</ng-container>
    <ng-template #form>
      <input type="text" class="form-control" [(ngModel)]="formModel" />
    </ng-template>
  </ng-template>
</td>
<td *ngIf="useEditButton">
  <edit-button-group [editing]="isEditing && updating" [deleting]="isDeleting && deleting" (onDelete)="delete()"
    (onEdit)="update()" (onEditModeEnabled)="enableEditMode()" (onEditModeDisabled)="disableEditMode()"
    (onDelete)="onEmit()">
  </edit-button-group>
</td>

1。

列表项目

I want to create a dynamic data table that will receive data from a backend server. The data will come in as an array of objects. Is there a way to dynamically create/bind a form group from the data that would allow inline editing for each row of the table and to update the changes when in edit mode. I don't want to hardcode data for the table each time unless I would have to. I am not able to use Angular Material for this project either. This is the component for the table row. The table functions as a data table but I can't seem to figure out how to make it editable.

import {
  Component,
  Input,
  Output,
  EventEmitter,
  ViewChild,
  ChangeDetectionStrategy,
} from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';
import { EditButtonGroupComponent } from '../../edit-button-group/edit-button-group.component';

@Component({
  selector: '[dataTableRow]',
  templateUrl: './data-table-row-form.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DataTableRowFormComponent {
  @ViewChild('editButtonGroup', { static: true })
  editButtonGroup: EditButtonGroupComponent;
  @Input() data: any[];
  @Input() formModel: any;
  @Input() useEditButton: boolean;
  @Input() updating: boolean;
  @Input() deleting: boolean;
  @Input() index: number;
  
  checkMark(value: any) {
    if (value === true) {
      return 'bi bi-check-lg';
    } else {
      return '';
    }
  }

  booleanCheck(val: any) {
    if (typeof val === 'boolean') {
      return true;
    } else {
      return false;
    }
  }

  returnZero() {
    return 0;
  }

  enableEditMode() {
    this.editModeEnabled = true;
    this.copyModel();
  }

  disableEditMode() {
    this.editModeEnabled = false;
    this.copyModel();
  }
  
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.0/angular.min.js"></script>

<td *ngFor="let y of data[index] | keyvalue : returnZero">
  <i [ngClass]="checkMark(y.value)" *ngIf="booleanCheck(y.value) else default"></i>
  <ng-template #default>
    <ng-container *ngIf="!editModeEnabled else form">{{y.value}}</ng-container>
    <ng-template #form>
      <input type="text" class="form-control" [(ngModel)]="formModel" />
    </ng-template>
  </ng-template>
</td>
<td *ngIf="useEditButton">
  <edit-button-group [editing]="isEditing && updating" [deleting]="isDeleting && deleting" (onDelete)="delete()"
    (onEdit)="update()" (onEditModeEnabled)="enableEditMode()" (onEditModeDisabled)="disableEditMode()"
    (onDelete)="onEmit()">
  </edit-button-group>
</td>

1.

List item

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冧九 2025-02-16 06:03:13

一样

<table >
    <thead>
        <tr >
            <th >Country</th>
            <th >Population</th>
            <th >GDP</th>
        </tr>
    </thead>
    <tbody *ngIf="formArray" >
        <tr  *ngFor="let item of formArray.controls;let i=index"
           [formGroup]="formGroup(i)">
            <td ><input formControlName="country"></td>
            <td ><input formControlName="population"></td>
            <td ><input formControlName="GDP"></td>
        </tr>
    </tbody>
</table>

要从formarray创建一个表,就像我们看到

  formGroup(i) {
    return this.formArray.at(i) as FormGroup;
  }

您使用getter获取FormGroup 。这样,您将neen'th将formarray封闭在一个formGroup内部,

但我们希望用innamy创建列,因此第一个是知道表的“列”

formArray = new FormArray([]);
columns: string[] = [];
headers: string[] = [];
editIndex: number = -1; //used to change the state to edit/show
oldValue:any;  //used to recover the changes

  @Input('data') set _data(value: any[]) {
    this.columns = Object.keys(value[0]);
    this.headers = this.columns.map(
      (x) => x[0].toUpperCase() + x.substr(1).toLowerCase()
    );
    this.formArray = new FormArray(value.map((data) => this.createGroup(data)));
  }

  createGroup(data: any=null) {

    if (!data)
    {
       data={};
       this.columns.forEach(x=>{
         data[x]=null;
       })
    }

    const formGroup = new FormGroup({});
    Object.keys(data).forEach((key: string) => {
      formGroup.addControl(key, new FormControl(data[key]));
    });
    return formGroup;
  }

。.html的“ .html”变成大约

<table >
    <thead>
        <tr>
            <th *ngFor="let head of headers">{{head}}</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let item of formArray.controls;let i=index"
            [formGroup]="formGroup(i)">
            <ng-container *ngIf="editIndex==i">
               <td *ngFor="let column of columns">
                 <input [formControlName]="column">
               </td>
            </ng-container>
            <ng-container *ngIf="editIndex!=i">
               <td *ngFor="let column of columns">
                   {{formArray.at(i).value[column]}}
               </td>
            </ng-container>
            <td><button (click)="edit(i)">
                   {{editIndex==i?'ok':'edit'}}
                </button>
                <button *ngIf="editIndex==i" (click)="cancel(i)">
                   cancel
                </button>
            </td>
        </tr>
    </tbody>
</table>

,我们有两个函数,编辑可以取消

  edit(index)
  {
    this.editIndex=this.editIndex==index?-1:index;
    this.oldValue={...this.formArray.at(index).value};

  }
  cancel(index)
  {
    this.formArray.at(index).setValue(this.oldValue);
    this.editIndex=-1;
  }

stackblitz

To create a table from a FormArray it's just some like

<table >
    <thead>
        <tr >
            <th >Country</th>
            <th >Population</th>
            <th >GDP</th>
        </tr>
    </thead>
    <tbody *ngIf="formArray" >
        <tr  *ngFor="let item of formArray.controls;let i=index"
           [formGroup]="formGroup(i)">
            <td ><input formControlName="country"></td>
            <td ><input formControlName="population"></td>
            <td ><input formControlName="GDP"></td>
        </tr>
    </tbody>
</table>

Where we has

  formGroup(i) {
    return this.formArray.at(i) as FormGroup;
  }

See that you use a getter to get the formGroup. In this way you neen'd enclosed the formArray inside a FormGroup

But we want create the columns dinamically, so the first is know the "columns" of your table

formArray = new FormArray([]);
columns: string[] = [];
headers: string[] = [];
editIndex: number = -1; //used to change the state to edit/show
oldValue:any;  //used to recover the changes

  @Input('data') set _data(value: any[]) {
    this.columns = Object.keys(value[0]);
    this.headers = this.columns.map(
      (x) => x[0].toUpperCase() + x.substr(1).toLowerCase()
    );
    this.formArray = new FormArray(value.map((data) => this.createGroup(data)));
  }

  createGroup(data: any=null) {

    if (!data)
    {
       data={};
       this.columns.forEach(x=>{
         data[x]=null;
       })
    }

    const formGroup = new FormGroup({});
    Object.keys(data).forEach((key: string) => {
      formGroup.addControl(key, new FormControl(data[key]));
    });
    return formGroup;
  }

The .html becomes like

<table >
    <thead>
        <tr>
            <th *ngFor="let head of headers">{{head}}</th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let item of formArray.controls;let i=index"
            [formGroup]="formGroup(i)">
            <ng-container *ngIf="editIndex==i">
               <td *ngFor="let column of columns">
                 <input [formControlName]="column">
               </td>
            </ng-container>
            <ng-container *ngIf="editIndex!=i">
               <td *ngFor="let column of columns">
                   {{formArray.at(i).value[column]}}
               </td>
            </ng-container>
            <td><button (click)="edit(i)">
                   {{editIndex==i?'ok':'edit'}}
                </button>
                <button *ngIf="editIndex==i" (click)="cancel(i)">
                   cancel
                </button>
            </td>
        </tr>
    </tbody>
</table>

And we have two functions, edit can cancel

  edit(index)
  {
    this.editIndex=this.editIndex==index?-1:index;
    this.oldValue={...this.formArray.at(index).value};

  }
  cancel(index)
  {
    this.formArray.at(index).setValue(this.oldValue);
    this.editIndex=-1;
  }

the stackblitz

表情可笑 2025-02-16 06:03:13

是的,这绝对是可能的。您需要创建一个表单阵列

最终,您需要将数据推入表单

  1. 为您推入表单组的数据创建数据结构。例如:
export interface TableRowData {
  ...whatever properties the data has here 
}
  1. 将数据推入表单阵列。看起来像:::
addRow(row: TableRowData): void {
  const row = new FormGroup({
    exampleProperty1: new FormControl(row.exampleProp1),
    exampleProperty2: new FormControl(row.exampleProp2),
  });
  this.table.push(row);
}
table: FormArray = new FormArray([]);

constructor(dataService: DataService) {
    // Fetch data from server
    this.dataService.getDataFromServer().subscribe((data: TableRowData[]) => {
        data.forEach(d => this.addRow(data));
    });

}

Yes, this is definitely possible. You'll need to create a form array.

Ultimately, you need to push your data into the form.

  1. Create a data structure for the data you'll push into the form group. For example:
export interface TableRowData {
  ...whatever properties the data has here 
}
  1. Push the data into the form array. It will look something like: :
addRow(row: TableRowData): void {
  const row = new FormGroup({
    exampleProperty1: new FormControl(row.exampleProp1),
    exampleProperty2: new FormControl(row.exampleProp2),
  });
  this.table.push(row);
}
table: FormArray = new FormArray([]);

constructor(dataService: DataService) {
    // Fetch data from server
    this.dataService.getDataFromServer().subscribe((data: TableRowData[]) => {
        data.forEach(d => this.addRow(data));
    });

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文