Реактивная форма с динамическими элементами управления - проблема с получением значения формы

У меня есть реактивная форма, которая динамически заполняется.

<form [formGroup]="productForm" (ngSubmit)="save();" novalidate>
    <table>
        <tr>
            <td style="padding-right: 20px">Steps</td> 
            <td style="padding-right: 20px">Estimated Completion Date:</td>
        </tr>
        <tr *ngFor="let product of products">
            <td style="padding-right: 20px">{{product.number}}. {{product.name}}</td>           
            <td style="padding-right: 20px">
                <md-input-container>
                    <input mdInput formControlName="estimatedDate" [mdDatepicker]="estimatedDate" placeholder="Choose a date" [value]="product.estimatedDate">
                    <button mdSuffix [mdDatepickerToggle]="estimatedDate" [value]="product.estimatedDate"></button>
                </md-input-container>
                <md-datepicker #estimatedDate></md-datepicker>
            </td>
        </tr>

    </table>
    <button md-raised-button (click)="save()">Done</button>
</form>

При сохранении я хочу создать массив значений формы.

this.products.forEach(product=> {
            this.resultArray.push({
                number: product.number,
                estimatedDate: this.productForm.value['estimatedDate']
            });

        } )

У меня есть 2 проблемы: - foreach дважды перебирает переменную products, поэтому я получаю двойное количество элементов в массиве. - поле предполагаемаяДата не определено. Правильно ли я обращаюсь к переменной формы? this.productForm.value['estimatedDate']


person Jay    schedule 18.07.2017    source источник
comment
Эй, Джей, тебе помог ответ или тебе нужна дополнительная помощь? :)   -  person AJT82    schedule 26.07.2017


Ответы (2)


Что касается вопроса о ссылке на переменную формы... рекомендуется метод get:

heroForm.get('name').value

Таким образом, ваш будет выглядеть примерно так:

this.productForm.get('estimatedDate').value

Что касается первого вопроса... если вы используете реактивные формы, вам не следует использовать привязку данных. Так что я немного смущен вашим кодом. Но проверьте как переменную products, так и переменную resultArray перед циклом, чтобы увидеть, не вызывают ли они проблему for/each.

person DeborahK    schedule 18.07.2017

На самом деле у вас там не реактивная форма. Я бы посоветовал вам реорганизовать свой код, чтобы у вас действительно была реактивная форма. Итак, мы строим форму, а также повторяем массив ваших продуктов и делаем его форматом. Кажется, вы хотите исключить name из формата, но если мы хотим использовать его в шаблоне, он нам нужен. Таким образом, мы можем отключить это поле, что исключает его из массива формы, но мы можем получить значение, используя getRawValue().

fb ниже относится к FormBuilder:

ngOnInit() {    
  this.productForm = this.fb.group({
    products: this.fb.array([])
  });
  // iterate products and create a formgroup for each object, pushed to array
  this.products.forEach(product => {
    this.productForm.get('products').push(this.fb.group({
      number:product.number, name:{value: product.name, disabled:true}, 
      estimatedDate:product.estimatedDate}))
  })
}

Затем в вашем шаблоне мы повторяем этот формат, отмечаем группу форм index и, наконец, отображаем имена элементов управления формы. Тогда важная часть вашей таблицы будет выглядеть так:

<tbody formArrayName="products">
 <tr *ngFor="let product of productForm.controls.products.controls; let i=index" [formGroupName]="i">
   <td>{{product.value.number}}. {{product.getRawValue().name}}</td>           
   <td>
     <md-input-container>
       <input mdInput formControlName="estimatedDate" [mdDatepicker]="estimatedDate" placeholder="Choose a date">
       <button mdSuffix [mdDatepickerToggle]="estimatedDate"></button>
     </md-input-container>
     <md-datepicker #estimatedDate></md-datepicker>
  </td>
 </tr>
</tbody>

Теперь у нас действительно есть реактивная форма! :) И объект формы теперь должен содержать объект, который вы хотите, или this.productForm.value.products - это массив, который вы хотите.

person AJT82    schedule 18.07.2017