问题
I've got two sections of forms - correspondence address and residential address. The goal is to copy/pass values from one field to another if a checkbox is checked. Kindly see below use case
- populate the correspondence address fields with the values of the residential address form fields iff a checkbox (same as residential address) is checked
- Should any form field in the residential address change after checking the checkbox, pass the change(s) realtime to the field in the correspondence
address and - lastly, clear the form values in the correspondence address if the checkbox is unchecked. Below is what i've tried
Component.ts
populateCorrespondenceAdd(event) {
//console.log(event.checked)
if (event.checked) {
[...]
this.correspondenceHouseNumber =
this.residentialHouseNumber;
this.correspondenceStreetName =
this.enrollee.residentialStreetName;
this.enrollee.correspondenceLGA =
this.enrollee.residentialLGA;
[...]
}
}
component.html
<mat-checkbox [(ngModel)]="populateCorrespondenceaddress" (change)="populateCorrespondenceAdd($event)"
formControlName="populateCorrespondenceadd" value="true">Same as residential address?)</mat-checkbox>
The code above doesn't quite meet expectation as (i) unchecking the checkbox doesn't clear the form fields (ii) after checking the checkbox, if there's any change(s) in any of the form fields in the residential address section, the correspondence form fields doesn't update to reflect the changes. N:B: The fields are in one form group
Kindly guide.
回答1:
I've simplified a bit your example and used:
- sending address
- billing address
Otherwise I think it's pretty much the same :)
TS
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormControl } from '@angular/forms';
import { EMPTY } from 'rxjs';
import { tap, distinctUntilChanged, switchMap, startWith } from 'rxjs/operators';
interface Address {
street: string;
city: string;
country: string;
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
public isSameAddressControl: FormControl = new FormControl(false);
public addresses: FormGroup = this.fb.group({
sendingAddress: this.fb.group({
street: '',
city: '',
country: ''
}),
billingAddress: this.fb.group({
street: '',
city: '',
country: ''
})
});
constructor(private fb: FormBuilder) { }
ngOnInit() {
this.isSameAddressControl
.valueChanges
.pipe(
distinctUntilChanged(),
switchMap(isSameAddress => {
if (isSameAddress) {
return this.addresses
.get('sendingAddress')
.valueChanges
.pipe(
// at the beginning fill the form with the current values
startWith(this.addresses.get('sendingAddress').value),
tap(value =>
// every time the sending address changes, update the billing address
this.addresses
.get('billingAddress')
.setValue(value)
)
)
} else {
this.addresses
.get('billingAddress')
.reset();
return EMPTY;
}
})
// don't forget to unsubscribe when component's destroyed
)
.subscribe();
}
}
HTML
<input type="checkbox" [formControl]="isSameAddressControl"> Same address for sending/billing
<form [formGroup]="addresses">
<ng-container formGroupName="sendingAddress">
Sending address<br>
<input type="text" formControlName="street" placeholder="Street" autocomplete="off"><br>
<input type="text" formControlName="city" placeholder="City" autocomplete="off"><br>
<input type="text" formControlName="country" placeholder="Country" autocomplete="off"><br>
</ng-container>
<ng-container formGroupName="billingAddress">
Billing address<br>
<input type="text" formControlName="street" placeholder="Street" autocomplete="off"><br>
<input type="text" formControlName="city" placeholder="City" autocomplete="off"><br>
<input type="text" formControlName="country" placeholder="Country" autocomplete="off"><br>
</ng-container>
</form>
Here's a working example on Stackblitz: https://stackblitz.com/edit/angular-nyjsnt
来源:https://stackoverflow.com/questions/52504991/angular-5-populate-form-fields-using-other-field-values-if-checkbox-is-selected