Предварительно заполнить поле ввода в `FormGroup` - Angular2

Я использую Angular2 - Reactive Forms. Все работает нормально, пока я не захочу показать предварительно заполненное значение в одном из полей формы.

Сценарий. На странице есть несколько кнопок, и каждая кнопка открывает форму с полями в виде

  1. Имя
  2. Эл. адрес
  3. Сообщение
  4. Код продукта -> Значение для этого должно быть предварительно указано в соответствии с кодом товара из службы.

Сценарий сбоя: входное значение кода продукта становится нулевым.

Код ТС:

import { FormGroup, FormBuilder, Validators } from '@angular/forms';
queryForm: FormGroup;
constructor(private _productService: ProductService, fb: FormBuilder) {
    this.queryForm = fb.group({
        'name': [null, Validators.compose([Validators.required, Validators.minLength(5)])],
        'email': [
            null, [Validators.required, Validators.email]
        ],
        'message': [null,Validators.compose([Validators.required, Validators.minLength(5)])],
        'pcode': [
            null
        ],
    })
}

HTML-форма:

<div *ngFor="let item of product">
<form action="#" [formGroup]="queryForm" 
 (ngSubmit)="submitForm(queryForm.value)" method="post" 
  novalidate="" class="text-left note" id="f_{{item.productId}}">
    [ .... rest of the fields ...]
    <div class="form-group hidden">
          <input type="hidden " class="form-control " id="pcode " name="pcode" 
        formControlName="pcode" [value]="item.productCode" />
     </div>
     <div class="form-group">
           <button type="submit" class="btn1" [disabled]="!queryForm.valid">Submit</button>
      </div>
</form>
</div>

Как я могу этого добиться?


person Gags    schedule 17.04.2017    source источник
comment
Обратите внимание, что в вашем вопросе упоминалось, что вы используете формы, управляемые шаблонами, но FormGroup, FormBuilder и т.д. предназначены для реактивных форм - это означает, что создание и управление вашими формами осуществляется из кода вашего компонента, а не из вашего шаблона - так какой подход вы намереваетесь использовать: шаблонный или реактивный?   -  person snorkpete    schedule 17.04.2017
comment
приведенный выше вопрос может показаться неуместным, но если вы не знаете, что делаете, смешение двух подходов просто запутает вас.   -  person snorkpete    schedule 17.04.2017
comment
Упс .. Реактивные формы   -  person Gags    schedule 17.04.2017


Ответы (1)


ОБНОВЛЕНИЕ. Как мы выяснили, вам нужен formArray вместо одного formControl. Итак, объявите, что при построении формы:

this.queryForm = this.fb.group({
  arrayOfData: this.fb.array([]) // name a proper name to array
})

Вы можете использовать setValue или patchValue, когда вы получили свои данные, где вы повторяете ответ и исправляете значения в своем массиве формы. Вызвать patchValues-метод в обратном вызове (подписаться).

patchValues() {
  const control = <FormArray>this.queryForm.get('arrayOfData');
  this.items.forEach(x => {
    control.push(this.patchValue(x.first_name, x.pcode))
  })
}

patchValue(name, code) {
  return this.fb.group({
    name: [name],
    pcode: [code]
  })    
}

В вашем шаблоне выполните итерацию по массиву форм, а также не забудьте установить имя группы форм (которое является индексом):

<div formArrayName="arrayOfData">
  <div *ngFor="let code of queryForm.get('arrayOFData').controls; let i = index">
    <div [formGroupName]="i">
      <label>Name: </label>
      <input formControlName="name" /><br>
      <label>Product Code: </label>
      <input formControlName="pcode" /><br>
    </div>
  </div>
</div>


Исходный ответ:

Вы всегда должны устанавливать значения формы в компоненте, а не в шаблоне. Вы можете использовать patchValue или setValue, когда получили значение от службы ... так что вы можете сделать это, например, внутри обратного вызова (подписаться):

this.myService.getSomeData()
  .subscribe(data => {
     this.item = data;
     this.queryForm.patchValue({pcode: this.item.productCode})
  });

Тогда вам не нужно использовать [value]="item.productCode" в вашей форме, вместо этого это значение устанавливается с помощью элемента управления формы.

person AJT82    schedule 17.04.2017
comment
Где мне нужно подписаться на это? - person Gags; 17.04.2017
comment
Ну, это просто пример, вы сказали, что получаете свое значение от службы, поэтому, когда вы получили свое значение для item, используйте patchValue, чтобы установить значение, которое вы получили :) - person AJT82; 17.04.2017
comment
Тогда этот pcode будет отображаться для каждой формы, которая у меня есть на странице? - person Gags; 17.04.2017
comment
все формы на странице, не понимаю, что вы имеете в виду ?? Кстати, обновленный ответ с демонстрацией. - person AJT82; 17.04.2017
comment
Это означает, что сервис возвращает набор продуктов и для каждого продукта существует несколько форм. Таким образом, каждая форма должна содержать значение pcode, возвращенное из службы для каждого продукта. - person Gags; 17.04.2017
comment
Я совершенно не понимаю, о чем вы говорите. Код нужно показать, иначе ничем не поможешь. Разверните плункер и воспроизведите проблему там, так что, возможно, я смогу помочь :) - person AJT82; 17.04.2017
comment
Давайте продолжим это обсуждение в чате. - person Gags; 17.04.2017
comment
http://plnkr.co/edit/3aTYorayo1gwboBeKIcH?p=preview .. Разветвил плункер ... если у меня несколько pcode в json .. то значения нет - person Gags; 17.04.2017
comment
Вам нужно выполнить итерацию и создать массив, если у вас несколько полей. FormControl работает только с одним значением. - person AJT82; 17.04.2017
comment
Ага .. это то, что я ищу ... любая помощь будет оценена :) - person Gags; 17.04.2017
comment
Обновленный ответ, теперь должно быть то, что вы хотите :) - person AJT82; 17.04.2017
comment
зачем создавать formArray внутри FormGroup? если вам нужен только formArray, используйте formArray напрямую - person Eliseo; 12.07.2021
comment
@Eliseo, конечно, если вам нужен только FormArray. OP использует форму с другими полями, зачем нам создавать отдельный formarray для этого, поскольку форма уже существует? - person AJT82; 12.07.2021