таблица mat с динамически добавляемыми строками и редактируемыми полями в строке с проверками - PullRequest
0 голосов
/ 29 сентября 2019

Я только начал работать над реактивными формами Angular, и я пытался создать таблицу, которая находится внутри формы.

В таблицу добавлена ​​новая функция, щелкнув ее, новая пустая строка будет вставлена ​​в таблицу.существующие строки будут в режиме редактирования по умолчанию, и они будут проверены.Данные таблицы будут сохранены с помощью одной кнопки сохранения, которая находится вне таблицы, но внутри формы.Я попробовал следующий код

constructor(private router: Router, private fb: FormBuilder) { }
  columnsToDisplay: string[];
  dataList;
  copyDataList;
  rows: FormArray = this.fb.array([]);
  formGroup: FormGroup = this.fb.group({ actualsVolumeData: this.rows });

  ngOnInit() {
    this.columnsToDisplay = ['id', 'code', 'desc'];

    this.formGroup = this.fb.group({
      columns: this.columnsToDisplay,
    });
    this.copyDataList = [];
    this.dataList = [];
    let list = [
      {
        code: 'one',
        desc: 'One1',
        id: 1
      },
      {
        code: 'two',
        desc: 'Two1',
        id: 2
      },
      {
        code: 'three',
        desc: 'Three1',
        id: 3
      },
    ];
    this.copyDataList = new MatTableDataSource(list);
    this.dataList = new MatTableDataSource(list);
  }

  onAdd() {
    let newRow = {
      id: this.dataList.data.length + 1,
      code: undefined,
      desc: undefined
    }
    this.copyDataList.data.push(newRow);
    this.dataList = new MatTableDataSource(this.copyDataList.data);
  }

  onSubmit() {

  }
<form [formGroup]=`formGroup`>
  <button mat-button (click)=`onAdd()`>Add</button>
  <table mat-table [dataSource]=`dataList` [formArrayName]=`actualsVolumeData` class=`mat-elevation-z8`>

    <ng-container matColumnDef=`id`>
      <th mat-header-cell *matHeaderCellDef> ID </th>
      <td mat-cell *matCellDef=`let element, let i = index` [formGroupName]=`i`> {{element.id}} </td>
    </ng-container>

    <ng-container matColumnDef=`code`>
      <th mat-header-cell *matHeaderCellDef> Code </th>
      <td mat-cell *matCellDef=`let element, let i = index` [formGroupName]=`i`> {{element.code}}
        <mat-form-field>
          <input matInput formControlName='code'>
        </mat-form-field>
      </td>
    </ng-container>

    <ng-container matColumnDef=`desc`>
      <th mat-header-cell *matHeaderCellDef> Description </th>
      <td mat-cell *matCellDef=`let element, let i = index` [formGroupName]=`i`> {{element.desc}}
        <mat-form-field>
          <input matInput formControlName=`desc`>
        </mat-form-field>
      </td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef=`columnsToDisplay`></tr>
    <tr mat-row *matRowDef=`let row; columns: columnsToDisplay;`></tr>
  </table>
<button mat-button (click)=`formGroup.valid && onSubmit()`>submit</button>
</form>

но я получаю эту ошибку this.validator не является функцией

1 Ответ

0 голосов
/ 29 сентября 2019

Как создать formArray из данных

Представьте, что у вас есть данные типа

[
 {code: 'one',desc: 'One1',id: 1},
 {code: 'two',desc: 'Two1',id: 2},
 {code: 'three',desc: 'Three1',id: 3}
]

. Для создания formArray полезно иметь функцию, которая получает объект и возвращает FormGroup

createFormGroup(data):FormGroup
{
   data=data|| {code:'',desc:'',id:0}
   return new FormGroup({
       code:new FormControl(data.code,Validators.required),
       desc:new FormControl(data.desc,Validators.required),
       id:new FormControl(data.id,Validators.required)
   })
}

если мы вызываем функцию с объектом, возвращаем formGroup, если мы вызываем функцию с нулем, возвращаем также FormGroup с пустыми элементами

Когда у вас есть данные, вы можете сделатьsimple

this.myFormArray=new FormArray(this.data.map(x=>this.createFormGroup(x)))

То есть каждый элемент данных, преобразованный в formGroup, formArray будет массивом с этими элементами.map преобразует каждый элемент «x» в «this.createFormGroup (x)» *

Если у вас есть служба, которая возвращает данные, на которые вы подписаны

this.myService.getData().subscribe(res=>{
     this.myFormArray=new FormArray(res.map(x=>x.this.createFormGroup(x)))
})

// у вашей службы есть метод, подобный

getData()
{
     return this.httpClient("http:myUrl")
}

Преимущество этого подхода в том, что для добавления нового элемента в FormArray вам нужно всего лишь сделать

this.formArray.push(this.createFormGroup(null)) 

Удалить

this.formArray.removeAt(index)

In stackblitz имеет небольшой пример всего этого.Ну, в сервисе я использую оператор rxjs of, как правило, был httpClient.get (url).Только я ставлю часть создания formArray,

ПРИМЕЧАНИЕ. Я использую конструктор FormGroup и конструктор FormArray, но вы можете использовать BuilderForm, например,

createFormGroup(data):FormGroup
{
   data=data|| {code:'',desc:'',id:0}
   return this.fb.group({
       code:[data.code,Validators.required],
       desc:[data.desc,Validators.required],
       id:[data.id,Validators.required]
   })
}

И использовать

myFormArray=this.fb.array(res.map(x=>x.this.createFormGroup(x)))
...