FormArray Показать значение поля ввода по умолчанию при изменении флажка - PullRequest
2 голосов
/ 10 июля 2020

У меня есть FormArray с двумя элементами управления, selectItem, который является флажком, и SelectAmount, который является текстовым полем ввода. Первоначально я показываю значения по умолчанию из массива объектов в поле ввода, которое можно редактировать, если установлен флажок. Теперь, если я сниму флажок, я хочу, чтобы в поле ввода отображалось значение по умолчанию, которое является свойством reversalAmount, как показано в коде. Может ли кто-нибудь помочь мне в этом.

            <ul formArrayName="items">
                <li class="reverse-list-item" *ngFor="let option of reversePaymentOptions ; let i=index" [formGroupName]="i">
                    <div class="select-all">
                        <mat-checkbox formControlName="selectItem" [(ngModel)]="reversePaymentOptions[i].isChecked" (change)="getSelectedItem(option)"></mat-checkbox>
                    </div>

                    <div class="reverse-amount-change" *ngIf="togglePartialReversalWithdrawal && option.PartialWithdrawEnabled">
                        <div class="form-control-wrapper">
                            <mat-form-field class="form-full-width">
                                <mat-label>GBP</mat-label>
                                <input type="text" matInput formControlName="selectAmount" (focus)="onfocusAmount(reversePaymentOptions[i])" [(ngModel)]="reversePaymentOptions[i].reversalAmount">
                            </mat-form-field>
                        </div>                            
                    </div>
                </li>
            </ul>
this.reversePaymentOptions = [
      {
        thumb: './assets/images/withdrawal/visa.svg.png',
        name: 'Visa',
        cardType: 'cc',
        reversalAmount: 20.00,
        isChecked: false,
        PartialWithdrawEnabled: true
      },
      {
        thumb: './assets/images/withdrawal/trustly.svg.png',
        name: 'Trustly',
        cardType: 'noncc',
        reversalAmount: 20.00,
        isChecked: false,
        PartialWithdrawEnabled: false
      },
      {
        thumb: './assets/images/withdrawal/paypal.svg',
        name: 'Paypal',
        cardType: 'wallet',
        reversalAmount: 10.00,
        isChecked: false,
        PartialWithdrawEnabled: true
      },
      {
        thumb: './assets/images/withdrawal/skrill.svg.png',
        name: 'Skrill',
        cardType: 'noncc',
        reversalAmount: 40.00,
        isChecked: false,
        PartialWithdrawEnabled: true
      },
      {
        thumb: './assets/images/withdrawal/maestro.svg.png',
        name: 'Maestro',
        cardType: 'noncc',
        reversalAmount: 10.00,
        isChecked: false,
        PartialWithdrawEnabled: true
      },
      {
        thumb: './assets/images/withdrawal/mastercard.svg.png',
        name: 'Master Card',
        cardType: 'noncc',
        reversalAmount: 30.00,
        isChecked: false,
        PartialWithdrawEnabled: true
      }
    ];

    ngOnInit() {
       this.form = this.formBuilder.group({      
         items: this.formBuilder.array([])
      });
      this.data();
      this.getTotalAmount();
    }

    get formArr() {
      return this.form.get('items') as FormArray;
    }

    this.reversePaymentOptions.map(d =>
      this.formArr.push(this.formBuilder.group({
        selectItem: new FormControl(d.isChecked),
        selectAmount: new FormControl(d.reversalAmount, [Validators.required, Validators.min(1), 
        Validators.max(d.reversalAmount)])
      }))
    );

Ответы [ 2 ]

0 голосов
/ 20 июля 2020

Я предложил другой подход, [ngModel] standalone , который получает значение reverse или значение formControl. Единственное, что вам нужно принять во внимание, - это при отправке значения в api проверять значения массива, и если он не отмечен, укажите значение по умолчанию

puff, в коде нам нужна одна функция для получения formArray

  get itemsArray()
  {
    return this.form.get('items') as FormArray
  }

Наш. html должен быть похож (смотрите, что мы перебираем itemsArray.controls). Обратите внимание: поскольку наша переменная, используемая для итерации по массиву, равна group, мы можем получить доступ к значению FormControl как group.get('selectItem') и group.get('selectAmount') (*)

<form [formGroup]="form">
    <ul formArrayName="items">
        <li class="reverse-list-item" *ngFor="let group of itemsArray.controls ; let i=index" [formGroupName]="i">
            <div class="select-all">
                <mat-checkbox formControlName="selectItem">
                  {{reversePaymentOptions[i].name}}
                </mat-checkbox>
            </div>
            <div class="reverse-amount-change">
                <div class="form-control-wrapper">
                    <mat-form-field class="form-full-width">
                        <mat-label>GBP</mat-label>
                        <input type="text" matInput
                           [ngModel]="group.get('selectItem').value?
                              group.get('selectAmount').value:
                              reversePaymentOptions[i].reversalAmount"
                           (ngModelChange)="group.get('selectItem').value &&
                              group.get('selectAmount').setValue($event)"
                           [ngModelOptions]="{standalone:true}"
                        >
                    </mat-form-field>
                </div>
            </div>
        </li>
    </ul>
</form>

Ah !, не забудьте в submit сделать что-то вроде

  submit(form:FormGroup)
  {
    if (form.valid)
    {
      form.value.items.forEach((x:any,index:number)=>{
        if (!x.selectItem)
          x.selectAmount=this.reversePaymentOptions[index].reversalAmount  
      })
    }
  }

(*) В некоторых версиях angular, в соответствии с ограничением машинописного текста, дайте ошибку, напрямую используйте переменную, перебирая элементы управления. Если это ваш случай, создайте вспомогательную функцию

  getGroup(index:number)
  {
    return (this.itemsArray.at(index) as FormGroup)
  }

и замените group.get(...) на getGroup(i).get(...)

a очень-очень уродливый stackblitz

Обновление иногда я забываю, что использую материал- angular, и вы можете получить / установить значение входных данных, используя [значение] и (изменить). Таким образом, вы можете использовать

<input type="text" matInput [disabled]="!group.get('selectItem').value"
                   [value]="group.get('selectItem').value?
                       group.get('selectAmount').value:
                       reversePaymentOptions[i].reversalAmount"
                   (change)="group.get('selectItem').value && 
                       group.get('selectAmount').setValue($event.target.value)"
                    
            >
0 голосов
/ 14 июля 2020

Поскольку вы используете ngModel, значения reversalAmount под reversePaymentOptions будут изменены, поэтому у вас нет возможности получить исходное значение. Итак, давайте сначала решим это, удалив все ngModel (вам это не нужно). Вместо этого используйте реализацию реактивной формы (которая у вас уже есть).

Также измените getSelectedItem() в HTML, чтобы передать в индекс элемента управления и checked статус:

<ul formArrayName="items">
  <li class="reverse-list-item" *ngFor="let option of reversePaymentOptions ; let i=index" [formGroupName]="i">
      <div class="select-all">
          <mat-checkbox formControlName="selectItem" (change)="getSelectedItem(option, i, $event.checked)"></mat-checkbox> <-- Notice the extra parameters in getSelectedItem
      </div>

      <div class="reverse-amount-change" *ngIf="togglePartialReversalWithdrawal && option.PartialWithdrawEnabled">
          <div class="form-control-wrapper">
              <mat-form-field class="form-full-width">
                  <mat-label>GBP</mat-label>
                  <input type="text" matInput formControlName="selectAmount" (focus)="onfocusAmount(reversePaymentOptions[i])" >
              </mat-form-field>
          </div>                            
      </div>
  </li>
</ul>

Если по какой-то причине вам требуется reversePaymentOptions, чтобы изменить их reversalAmount, создайте новую копию массива без ссылки (используя такие вещи, как loda sh cloneDeep)

В TS изменить getSelectedItem:

getSelectedItem(option, index, checked) {
  ...
  if (!checked) {
   this.formArr.controls[index].get('selectAmount').setValue(this.reversePaymentOptions[index].reversalAmount);
  }
  
}

...