Как передать значения из группы форм в другое время в режиме реального времени в виде двусторонней привязки данных в реактивной форме? - PullRequest
0 голосов
/ 12 апреля 2020

У меня есть 2 FormGroups, orderForm и parcelForm на странице, и parcelForm динамически генерируется в FormArray. parcelForm имеет FormControl, как net_weight, gross_weight и OrderForm имеет FormControl, то есть total_net_weight и total_gross_weight. Я хочу связать два значения parcelForm FormControl net_weight и gross_weight, чтобы каждый раз, когда пользователь динамически добавлял parcelForm и вводил значения для FormControl net_weight и gross_weight, он отражал total_net_weight и total_gross_weight FormControl orderForm. Я пробовал функцию patchValue, такую ​​как this.parcelForm.get('parcels').patchValue([iterator, 'net_weight']), а также this.parcelForm.get('parcels').get([iterator, 'net_weight']).value, но безуспешно. Это new-order.page.ts:

import { Component, OnInit } from '@angular/core';
import { Order } from 'src/app/models/order.model';
import { FormGroup, FormControl, Validators, FormArray } from '@angular/forms';
import { OrderService } from 'src/app/services/order.service';
import { NavController, ModalController, ActionSheetController } from '@ionic/angular';
import { ActivatedRoute } from '@angular/router';


@Component({
  selector: 'app-new-order',
  templateUrl: './new-order.page.html',
  styleUrls: ['./new-order.page.scss'],
})
export class NewOrderPage implements OnInit {
  @Output() formChange = new EventEmitter();
  pageTitle: string;
  orders: Order[];
  order: Order;
  orderForm: FormGroup;
  parcelForm: FormGroup;
  error;

  number_of_parcel = 0;
  total_net_weight = 0;
  total_gross_weight= 0;

  constructor(
    private orderService: OrderService,
  ) { }

  ngOnInit() {
    this.getAllDestionation();
    this.orderService.getAllOrders()
      .subscribe(
        data => this.orders = data
      );
    this.orderForm = new FormGroup({

      number_of_parcel: new FormControl(null, {
        updateOn: 'blur',
        validators: [Validators.required, Validators.min(1)]
      }),
      total_net_weight: new FormControl(null, {
        updateOn: 'blur',
        validators: [Validators.required, Validators.min(1)]
      }),
      total_gross_weight: new FormControl(null, {
        updateOn: 'blur',
        validators: [Validators.required, Validators.min(1)]
      })
    });

    this.parcelForm = new FormGroup({
      parcels: new FormArray([])
    });

    this.formChange.emit(this.parcelForm);
  }



  onSubmit() {
    this.mapFormValuesToOrderModel();
    if (this.order.id) {
      this.orderService.updateOrder(this.order).subscribe(
        () => {
          this.goBack();
        },
        (err: any) => this.error = err
      );
    } else {
      this.orderService.createOrder(this.order).subscribe(
        (data) => {
          this.orders.push(data);
          this.goBack();
        },
        (err: any) => this.error = err);
    }
  }




  goBack(): void {
    this.navController.navigateRoot('/members/menu/tabs/orders');
  }

  onClick() {
    console.log(this.orderForm);
  }


  parcels(): FormArray {
    return this.parcelForm.get('parcels') as FormArray;
  }

  newParcelFormGroup(): FormGroup {
    return new FormGroup({
      net_weight: new FormControl(null, {
        updateOn: 'blur',
        validators: [Validators.required, Validators.min(1)]
      }),
      gross_weight: new FormControl(null, {
        updateOn: 'blur',
        validators: [Validators.required, Validators.min(1)]
      }),
    });
  }

  addParcelButtonClick() {
    this.parcels().push(this.newParcelFormGroup());
    this.number_of_parcel++;

    let num = [];
    let iterator = 0;
    for (iterator = 0; iterator < this.number_of_parcel; iterator++) {
      console.log(this.parcelForm.get('parcels').get([iterator, 'net_weight']).valueChanges);

      num.push(Number(this.parcelForm.get('parcels').get([iterator, 'net_weight']).value));

    }

    console.log(num);

  }

  removeParcel(parcelIndex: number) {
    this.parcels().removeAt(parcelIndex);
    this.number_of_parcel--;
  }

  onChanges(): void {
    console.log('parcelForm > onChanges', this.parcelForm.value);
    this.parcelForm.valueChanges.subscribe(value => {
      this.formChange.emit(this.parcelForm);
    });
  }

}

Это new-order.page.html:

<ion-header>
  <ion-toolbar color="dark">
    <ion-title>{{pageTitle}}</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-row>
    <ion-col size-md="8" offset-md="2">

      <form [formGroup]="orderForm">        
        <ion-item *ngIf="hideTemplate">
          <ion-label position="fixed">No. of Parcels</ion-label>
          <ion-input type="text" autofocus formControlName="number_of_parcel">{{number_of_parcel}}</ion-input>
        </ion-item>
        <ion-label
          *ngIf="orderForm.get('number_of_parcel').hasError('required') && orderForm.get('number_of_parcel').touched">
          Name can't be empty!
        </ion-label>
        <ion-item>
          <ion-label position="fixed">Total Net Weight</ion-label>
          <ion-input type="text" autofocus formControlName="total_net_weight">{{total_net_weight}}</ion-input>
        </ion-item>
        <ion-label
          *ngIf="orderForm.get('total_net_weight').hasError('required') && orderForm.get('total_net_weight').touched">
          Name can't be empty!
        </ion-label>
        <ion-item>
          <ion-label position="fixed">Total Gross Weight</ion-label>
          <ion-input type="text" autofocus formControlName="total_gross_weight"></ion-input>
        </ion-item>
        <ion-label
          *ngIf="orderForm.get('total_gross_weight').hasError('required') && orderForm.get('total_gross_weight').touched">
          Name can't be empty!
        </ion-label>
      </form>
      <br>
      <br>

      <ion-row>
        <ion-col size="4" offset="10">
          <ion-button color="success" (click)="addParcelButtonClick()">
            <ion-icon name="add-outline"></ion-icon>Add Parcel
          </ion-button>
        </ion-col>
      </ion-row>
      <form [formGroup]="parcelForm">
        <div formArrayName="parcels">
          <div *ngFor="let parcel of parcels().controls; index as parcelIndex;">
            <div [formGroupName]="parcelIndex">
              Parcel {{parcelIndex + 1}}:
              <ion-item>
                <ion-label position="floating">Net Weight</ion-label>
                <ion-input type="text" formControlName="net_weight"></ion-input>
              </ion-item>
              <ion-label *ngIf="parcel.get('net_weight').hasError('required') && parcel.get('net_weight').touched">
                Remarks can't be empty!
              </ion-label>
              <ion-item>
                <ion-label position="floating">Gross Weight</ion-label>
                <ion-input type="text" formControlName="gross_weight"></ion-input>
              </ion-item>
              <ion-label *ngIf="parcel.get('gross_weight').hasError('required') && parcel.get('gross_weight').touched">
                Remarks can't be empty!
              </ion-label>

              <br>
              <ion-row>
                <ion-col size="4" offset="10">
                  <ion-button color="danger" (click)="removeParcel(parcelIndex)">Remove <ion-icon name="trash-outline">
                    </ion-icon>
                  </ion-button>
                </ion-col>
              </ion-row>
            </div>
          </div>
        </div>
      </form>


    </ion-col>
  </ion-row>
</ion-content>

1 Ответ

1 голос
/ 15 апреля 2020

Мне удалось получить значения следующим образом:

this.parcelForm.get('parcels').get([this.iterator, 'net_weight']).valueChanges.subscribe(
      data => this.total_net_weight += data
    );

Мне не пришлось вносить какие-либо изменения во внешний интерфейс.

Это моя addParcelButtonClick() функция в итоге выглядела как

  async addParcelButtonClick() {
    this.parcels().push(this.newParcelFormGroup());
    this.iterator = this.number_of_parcel;
    let gross_weight = 0;

    this.parcelForm.get('parcels').get([this.iterator, 'net_weight']).valueChanges.subscribe(
      data => this.total_net_weight += data
    );
    this.parcelForm.get('parcels').get([this.iterator, 'gross_weight']).valueChanges.subscribe(
      data => {
        this.total_gross_weight += data;
        gross_weight = data;
      }
    );


    this.getOrderFormValues();
    this.number_of_parcel++;

  }

Это getOrderFormValues() функция:

getOrderFormValues() {
    this.orderForm.setValue({
      total_net_weight: this.total_net_weight,
      total_gross_weight: this.total_gross_weight
    });
  }

И это removeParcel функция:

async removeParcel(parcelIndex: number) {
    // this.iterator = this.number_of_parcel;
    if (this.parcelForm.get('parcels').get([parcelIndex, 'net_weight'])) {
      this.total_net_weight -= await this.parcelForm.get('parcels').get([parcelIndex, 'net_weight']).value;
      this.total_gross_weight -= await this.parcelForm.get('parcels').get([parcelIndex, 'gross_weight']).value;

    }
    this.parcels().removeAt(parcelIndex);
    this.number_of_parcel--;
    this.getOrderFormValues();
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...