Как работать с выпадающим списком в formarray в Angular?

#angular

Вопрос:

изображениеЗдесь я пытаюсь динамически выбрать значение выпадающего списка , но проблема, с которой я сталкиваюсь, заключается в том, что при выборе значения в выпадающем списке я извлекаю из него объект, и из него я пытаюсь установить значение цены за единицу в поле цена за единицу, но оно устанавливается в каждом поле цена за единицу, как правило, это должно быть для определенного индекса . Мы будем признательны за любую помощь

          <form [formGroup]="myForm" (ngSubmit)="onSubmit()">
                      <div formArrayName="arr" *ngFor="let a of myForm.get('arr').controls; let i = index">
                        <div [formGroupName]="i" style="margin-bottom: 10px;" class="form-inline">
                          <div class="form-group">
                            <div class="col-sm-12">
                              <label>ProdName :</label>
                              <select name="productnames" formControlName="productnames" id="productnames"
                                class="form-control form-control-element" 
                               >
                                <option *ngFor="let catalog of productlist" [ngValue]="catalog">
                                  {{catalog.productname}}
                                </option>
                              </select>
                            </div>
                          </div>
                       </div>
                      </div>
margin: 0 inherit;" />
  <div class="form-group">
                    <div class="col-sm-12">
                      <label>UnitPrice :</label>
                      <input type="text" name="unitprices" size="10" value="{{unitprices}}" formControlName="unitprices">
                    </div>
                  </div>
                </div>
              </div>
     <input type="submit" id="submit" class="btn btn-danger btn-lg active" (click)="onSubmit()"
                  value="AddElement" style="text-align: center;
 

TsФайл:-

   ngOnInit() {
    this.myForm = this.fb.group({
      arr: this.fb.array([this.createItem()])
    })
    this.getallproductname(event)
  }

 getallproductname(event) {
    const base_URL = 'http://localhost:9007/api/excel/getAllList'
    this.http.get(base_URL,).subscribe(data => {
      this.productlist.push(data)
      this.productlist = this.productlist[0]
    
    })

createItem() {
    return this.fb.group({
      quantities: [''],
      unitprices: [''] ,
      totalprices:[''],
      productnames:['']
    })
  }

 onSubmit() {
   
    console.log(this.myForm.value);
  }
 

Возвращаемый объект :-

  {
          "productid": 1,
          "productname": "RO",
          "imagepath": "./assets/1.jpeg",
          "unitprice": "4000",
          "productdescription": "Faber FWP Galaxy PRO Reverse Osmosis Water Purifier 7L, black, ro mat",
          "warrantydays": "90",
          "totalamount": 0,
          "quantity": 3
        }
 

Комментарии:

1. можно ли поделиться рабочим кодом, как в stackblitz?

2. Добавлено изображение для получения дополнительной информации , пожалуйста, проверьте

3. в <select> теге вы добавили оба formControlName="productnames" или [(ngModel)]="productnames" . удалите [(ngModel)]="productnames" и затем попробуйте.

4. @neilnikkunilesh , добавлено

5. работает ли это сейчас?

Ответ №1:

Если вы используете formControlName в FormArray, то нет необходимости использовать ngmodel . Он будет привязан ко всем компонентам формы и синхронизируется с той же переменной, которую вы используете в .ts файле.

[(ngmodel)] принимает модель предметной области в качестве дополнительного ввода. Если у вас односторонняя привязка к ngModel с синтаксисом [], изменение значения модели предметной области в классе компонентов задает значение в представлении. Если у вас двусторонняя привязка с синтаксисом [()] (также известным как синтаксис «банан в коробке»), значение в пользовательском интерфейсе всегда синхронизируется с моделью предметной области в вашем классе

В вашем случае для <select> тега вы добавили оба formControlName="productnames" или [(ngModel)]="productnames" . Удалите[(ngModel)]=»имена продуктов».

Комментарии:

1. В случае цены за единицу, которая поступает из выпадающего списка, как это исправить @neilnikkunilesh

Ответ №2:

Когда мы пишем что-то вроде:

 <select name="productnames" formControlName="productnames">
   <option *ngFor="let catalog of productlist" [ngValue]="catalog">
      {{catalog.productname}}
   </option>
</select>
 

в вашем элементе управления формой «имена продуктов» на самом деле у вас есть полный объект-выбранный calagod. Причина в том , что вы пишете [ngValue]="catalog" , А НЕ, например [ngValue]="catalog.productid"

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

Таким образом, мы можем использовать входные данные только для чтения с

 <input readonly [value]="myForm.get('arr').value[i].unitprices"> //(*)
 

И еще один такой же

 <input readonly [value]="( myForm.get('arr').value[i].unitprices)*
                 ( myForm.get('arr').value[i].quantities)"> //(*)
 

Убедитесь, что ввод не является «FormControl», не имеет formControlName или [formControl] , и элементы вашего FormArray действительно сильно отличаются от того, что вы ожидаете. На самом деле ваши товары должны быть такими:

 createItem() {
    return this.fb.group({
      productnames:['']
      quantities: [''],
    })
  }
 

И один элемент будет похож,например

 {
   productnames:{
      "productid": 1,
      "productname": "RO",
      "imagepath": "./assets/1.jpeg",
      "unitprice": "4000",
      "quantity":3,
      ....
   },
   quantities:20,
}
 

Ну, это правда, что перед отправкой данных в службу de нам нужно создать объект, используя myForm.value

ПРИМЕЧАНИЕ: обычно только для проверки мы пишем в нашем .html что-то вроде

 <pre>
{{myForm.value|json}}
</pre>
 

(*) действительно всегда, когда мы хотим работать с FormArrays, мы должны использовать геттер

 get catalogFormArray()
{
    return this.myForm.get('arr') as FormArray
}
 

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

 <input readonly [value]="catalogFormArray.value[i].unitprices">

<input readonly [value]="( catalogFormArray.value[i].unitprices)*
                 ( catalogFormArray.value[i].quantities)">