具有多个输入的FormControlName的ControlValueAccessor

时间:2018-07-14 11:37:46

标签: angular angular-reactive-forms

我想通过实现ControlValueAccessor创建自定义表单元素地址。

我试图创建一个AddressComponent,在其中我有多个输入字段。我想在如下所示的反应形式中使用此组件。

  

address.component.html

<form name="form" class="form_main" #addForm="ngForm" (ngSubmit)="addForm.form.valid && saveAddress()" [formGroup]="addressForm">
  <!-- Address 1 -->
  <mat-form-field class="form-field">
    <input matInput placeholder="Address 1" formControlName="address1" required>
    <mat-error *ngIf="addressForm.get('address1').hasError('required')">
      *Required field
    </mat-error>
  </mat-form-field>

  <!-- Address 2 -->
  <mat-form-field class="form-field">
    <input matInput placeholder="Address 2" formControlName="address2">
  </mat-form-field>

  <!-- Address 3 -->
  <mat-form-field class="form-field">
    <input matInput placeholder="Address 3" formControlName="address3">
  </mat-form-field>

  <!-- Country -->
  <mat-form-field class="form-field">
    <input matInput placeholder="Country" formControlName="country" required>
    <mat-error *ngIf="addressForm.get('country').hasError('required')">
      *Required field
    </mat-error>
  </mat-form-field>

  <!-- State -->
  <mat-form-field class="form-field">
    <input matInput placeholder="State" formControlName="state">
  </mat-form-field>

  <!-- City -->
  <mat-form-field class="form-field">
    <input matInput placeholder="City" formControlName="city" required>
    <mat-error *ngIf="addressForm.get('city').hasError('required')">
      *Required field
    </mat-error>
  </mat-form-field>
</form>
  

address.component.ts

export class AddressComponent implements OnInit, ControlValueAccessor {

  @ViewChild('addForm')
  public addForm: FormControlName;
  @Input() parentForm: NgForm;
  public addressForm: FormGroup;
  private _address: any = {};
  constructor(
    private fb: FormBuilder,
  ) { }

  ngOnInit() {
    this.addressForm = this.fb.group({
      address1: ['', [Validators.required]],
      address2: [''],
      address3: [''],
      country: ['', [Validators.required]],
      state: ['', [Validators.required]],
      city: ['', [Validators.required]],
    });
  }

  saveAddress() {
    console.log(this._address);
    console.log(this.addressForm.getRawValue());
  }

  propagateChange = (_: any) => {};

  writeValue(obj: any) {
    console.log(obj);  //<-- always getting null
   // this.addForm = obj;  
   // this._address = obj; 
  }

  registerOnChange(fn: any) {
    this.propagateChange = fn;
  }
  registerOnTouched(fn: any) {
    this.propagateChange = fn;
  }
}
  

customer-registration.component.html    

                    <!-- Organization Name -->
                    <mat-form-field class="form-field">
                        <input matInput placeholder="Organization Name" formControlName="cutomerName" required>
                        <mat-error *ngIf="custForm.get('cutomerName').hasError('required')">
                            *Required field
                        </mat-error>
                    </mat-form-field>

                    <!-- Organization Code -->
                    <mat-form-field class="form-field">
                        <input matInput placeholder="Organization Code" formControlName="cutomerCode" required>
                        <mat-hint></mat-hint>
                        <mat-error *ngIf="custForm.get('cutomerCode').hasError('required')">
                            *Required field
                        </mat-error>
                        <mat-error *ngIf="custForm.get('cutomerCode').hasError('isEmployeIdUnique')">
                            Organization Code already available in the system
                        </mat-error>
                    </mat-form-field>

                    <!-- Website -->
                    <mat-form-field class="form-field">
                        <input matInput placeholder="Website" formControlName="website">
                    </mat-form-field>

                    <!-- Telephone -->
                    <mat-form-field class="form-field">
                        <input matInput placeholder="Telephone" name="customerForm.telephone" formControlName="telephone">
                    </mat-form-field>

                    <app-address [parentForm]="primaryAddress" formControlName="primaryAddress" #primaryAddress></app-address>

                    <div class="button-group">
                        <button type="submit" [disabled]="loading" class="btn btn-submit">Submit</button>
                        <button (click)="custForm.reset()" class="btn btn-outline-submit">reset</button>
                    </div>

                </form>
  

customer-registration.component.ts

    export class CustomerRegistrationComponent implements OnInit {

  @ViewChild('primaryAddress')
  private primaryAddress: AddressComponent;

  public customerForm: NgForm;
  public custForm: FormGroup;
  constructor(
    private fb: FormBuilder,
  ) { }

  ngOnInit() {
    this.custForm = this.fb.group({
      cutomerName: ['', [Validators.required]],
      cutomerCode: ['', [Validators.required]],
      website: [''],
      telephone: ['', [
        Validators.pattern(/^[0-9 ]{1,15}$/)
      ]],
      primaryAddress: new FormControl(),
    });
  }

  registerCusomer() {
    console.log(this.custForm.getRawValue());  //<---- not getting primaryAddress details
    this.primaryAddress.saveAddress();
  }
}

我不知道为什么在调用this.custForm.getRawValue() onSubmit表单时没有得到primaryAddress详细信息。

1 个答案:

答案 0 :(得分:4)

将此代码添加到registerOnChange

this.addressForm.valueChanges.subscribe(() => {
  fn(this.addressForm.value);
});