我想通过实现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详细信息。
答案 0 :(得分:4)
将此代码添加到registerOnChange
:
this.addressForm.valueChanges.subscribe(() => {
fn(this.addressForm.value);
});