Angular 9.0 - FormGroup and FormArray - remove row from table

爱⌒轻易说出口 提交于 2021-02-10 05:12:39

问题


I've tried trying to remove a row using a button click, but it doesn't work and I'm not so sure what can I do to solve this issue.

Initial json displayed is:

{ "list": [ { "description": null, "status": false } ] }

When I click the Remove button, the json displayed will become:

{ "list": [] }

AND the selected row is not removed at all.

Here's the codes below.

todo-list.component.ts

todoListForm: FormGroup;

  constructor(private toDoService: TodoService, private formBuilder: FormBuilder) {
    this.createForm();
  }

  tableData: TableData[] = [
    { id: 'aaaaa', description: 'Go to market', status: true },
    { id: 'bbbbb', description: 'Buy groceries', status: true },
    { id: 'ccccc', description: 'Order pizza delivery', status: false },
  ];

  ngOnInit(): void { }

  createForm() {
    this.todoListForm = this.formBuilder.group({
      list: this.formBuilder.array([])
    });

    this.addList();
  }

  get list(): FormArray {
    return this.todoListForm.get('list') as FormArray;
  }

    addList(): void {
      const addTodoListForm = this.formBuilder.group({
        description: [null, Validators.required],
        status: [false]
      });
  
      this.list.push(addTodoListForm);
  
      console.log('addTodoListForm', addTodoListForm);
      console.log('list', this.list);
    }

  removeRow(i: number): void {
    console.log(this.list);
    this.list.removeAt(i);
  }
}

export interface TableData {
  id: string,
  description: string,
  status: boolean,
}

todo-list-component.html

<h1> To-do List </h1>
{{ todoListForm.value | json}}
<form [formGroup]="todoListForm">
    <div formArrayName="list">
        <div class="tableFlex">
            <table class="table table-striped" table-layout="fixed">
                <tr>
                    <th> #ID </th>
                    <th> Description </th>
                    <th> Action </th>
                </tr>
                <tr *ngFor="let data of tableData, let i = index">
                    <td> {{ i + 1 }} </td>
                    <td> <del *ngIf="data.status === true">{{data.description}}</del>
                        <div *ngIf="data.status === false">{{data.description}}</div>
                    </td>
                    <td>
                        <div class="btn-toolbar pull right">
                            <div class="btn-group mr-2" role="group" aria-label="Mark-as">
                                <button type="button" class="btn btn-secondary" (click)="updateStatus(i, data.status)">
                                    {{ data.status === true ? 'Mark as incomplete' : 'Mark as completed' }} </button>
                            </div>

                            <div class="btn-group mr-2" role="group" aria-label="Remove">
                                <button type="submit" class="btn btn-danger" (click)="removeRow(i)">
                                    Remove
                                </button>
                            </div>
                        </div>
                    </td>
                </tr>
            </table>
        </div>
    </div>
</form>

回答1:


try this out by adding change detector ref

constructor(private readonly changeDetectorRef: ChangeDetectorRef){

}

  removeRow(i: number): void {
    this.list.removeAt(i);
    this.changeDetectorRef.markForCheck();
  }

if this doesn't work try this.detectChanges() as well. If this also not work ur changes are running out of the ng Zone then u can try out below thing

  removeRow(i: number): void {
       this.zone.run(() => this.list.removeAt(i););
      }

inject Zone to this file as well




回答2:


You has a FormArray (and add elements to the formArray and remove from this), BUT you are iterating over tableData, this has no sense

First create a function that return a formGroup (more like than your addList)

createGroup(data=null)
{
  data=data || {} as TableData 
  return this.formBuilder.group({
        id:[data.id],
        description: [data.description, Validators.required],
        status: [data.status]
      });
}

When you create the formGroup you can use this fucntion as

this.todoListForm = this.formBuilder.group({
  list: this.formBuilder.array(this.tableData.map(x=>this.createGroup(x))
});

See how transform the array tableData in an array of FormGroup using map

When you iterate iterate over list.controls

<tr *ngFor="let data of list.controls, let i = index" [formGroupName]="i">
  <!--use list.at(i).get('description').value-->
  {{list.at(i).get('description').value}}
  <!-- and list.at(i).get('status').value, e.g.-->
  <div *ngIf="list.at(i).get('status').value"></div>
</tr>

And forget the ngZone, changeDetectorRef and another "strange things"



来源:https://stackoverflow.com/questions/64003106/angular-9-0-formgroup-and-formarray-remove-row-from-table

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!