我输入的代码只涉及一个字段。在本例中,Country 字段工作正常。
我需要让 State 和 City 字段正常工作。
我需要在另一个字段中选择国家列表时自动完成“州”,列出与该国家相关的那些,并在选择一个州时,列出与该州相关的城市。
我使用选择组件具有此功能。
<mat-expansion-panel class="mat-elevation-z4" [expanded]="true">
<mat-expansion-panel-header>
<mat-panel-title>
<mat-icon fontSet="fa" fontIcon="fa-map-marker" fxLayoutAlign="start center"></mat-icon>
<span>Endereços</span>
</mat-panel-title>
</mat-expansion-panel-header>
<ng-template>Localização</ng-template>
<mat-slide-toggle (change)="checkCopyValuesAddress($event)" [color]="'primary'">Considerar
os
mesmos dados do endereço de faturamento.</mat-slide-toggle>
<mat-tab-group mat-stretch-tabs id="main">
<mat-tab *ngFor="let tab of getFormArray(identificationFormGroup, 'addresses');let i= index"
[label]="i === 0 ? 'Faturamento' : i === 1 ? 'Cobrança' : 'Entrega'" formArrayName="addresses"
#addresses>
<div [formGroupName]="i">
<div class="row">
<div class="col-sm-4">
<mat-form-field class="full-width">
<mat-label>Pais...</mat-label>
<mat-select [compareWith]="objectComparisonFunction" formControlName="country" #country
required>
<mat-option>-- Selecione --</mat-option>
<mat-option *ngFor="let country of countryList" [value]="country">
{{country.name}} - {{country.initialsCode}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-sm-4">
<mat-form-field class="full-width">
<mat-label>Estado...</mat-label>
<mat-select [compareWith]="objectComparisonFunction" formControlName="state" #state
required>
<mat-option>-- Selecione --</mat-option>
<mat-option *ngFor="let state of stateList" [value]="state">
{{state.name}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-sm-4">
<mat-form-field class="full-width">
<mat-label>Cidade...</mat-label>
<mat-select [compareWith]="objectComparisonFunction" formControlName="city" #city required>
<mat-option>-- Selecione --</mat-option>
<mat-option *ngFor="let city of cityList" [value]="city">
{{city.name}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-md-9">
<mat-form-field class="full-width">
<input matInput placeholder="Endereço... " formControlName="address" #address
maxlength="100" required>
<button mat-button
*ngIf="(address.value && i == 0) || ((address.value && i > 0) && !copyValueAddress)"
[disabled]="address.disabled" matSuffix mat-icon-button aria-label="Clear"
(click)="clearFieldArrayControl(identificationFormGroup, 'addresses', 'address', i)">
<mat-icon>close</mat-icon>
</button>
<mat-hint align="end">
{{address.value.length}}/100.
</mat-hint>
</mat-form-field>
</div>
<div class="col-sm-3">
<mat-form-field class="full-width">
<input matInput placeholder="Número..." formControlName="addressNumber" #addressNumber
maxlength="7" required>
<button mat-button
*ngIf="(addressNumber.value && i == 0) || ((addressNumber.value && i > 0) && !copyValueAddress)"
[disabled]="addressNumber.disabled" matSuffix mat-icon-button aria-label="Clear"
(click)="clearFieldArrayControl(identificationFormGroup, 'addresses', 'addressNumber', i)">
<mat-icon>close</mat-icon>
</button>
<mat-hint align="end">
{{this.addressNumber.value.length}}/7.
</mat-hint>
</mat-form-field>
</div>
<div class="col-md-3">
<mat-form-field class="full-width">
<input #cep matInput placeholder="CEP... " formControlName="addressZipCode" #addressZipCode
minlength="8" mask="00.000-000" required>
<button mat-button
*ngIf="(addressZipCode.value && i == 0) || ((addressZipCode.value && i > 0) && !copyValueAddress)"
[disabled]="addressZipCode.disabled" matSuffix mat-icon-button aria-label="Clear"
(click)="clearFieldArrayControl(identificationFormGroup, 'addresses', 'addressZipCode', i)">
<mat-icon>close</mat-icon>
</button>
<mat-hint align="end">
{{this.addressZipCode.value.replace('.', '').replace('-', '').length}}/8.
</mat-hint>
</mat-form-field>
</div>
<div class="col-md-6">
<mat-form-field class="full-width">
<input matInput placeholder="Complemento... " formControlName="addressComplement"
#addressComplement maxlength="100">
<button mat-button
*ngIf="(addressComplement.value && i == 0) || ((addressComplement.value && i > 0) && !copyValueAddress)"
[disabled]="addressComplement.disabled" matSuffix mat-icon-button aria-label="Clear"
(click)="clearFieldArrayControl(identificationFormGroup, 'addresses', 'addressComplement', i)">
<mat-icon>close</mat-icon>
</button>
<mat-hint align="end">
{{this.addressComplement.value.length}}/100.
</mat-hint>
</mat-form-field>
</div>
<div class="col-sm-3">
<mat-form-field class="full-width">
<input matInput placeholder="Bairro..." formControlName="addressNeighborhood"
#addressNeighborhood maxlength="25" required>
<button mat-button
*ngIf="(addressNeighborhood.value && i == 0) || ((addressNeighborhood.value && i > 0) && !copyValueAddress)"
[disabled]="addressNeighborhood.disabled" matSuffix mat-icon-button aria-label="Clear"
(click)="clearFieldArrayControl(identificationFormGroup, 'addresses', 'addressNeighborhood', i)">
<mat-icon>close</mat-icon>
</button>
<mat-hint align="end">
{{this.addressNeighborhood.value.length}}/25.
</mat-hint>
</mat-form-field>
</div>
<hr>
<div class="col-md-4">
<mat-form-field class="full-width">
<input matInput placeholder="Contato... " formControlName="contactName" #contactName
maxlength="100" required>
<button mat-button
*ngIf="(contactName.value && i == 0) || ((contactName.value && i > 0) && !copyValueAddress)"
[disabled]="contactName.disabled" matSuffix mat-icon-button aria-label="Clear"
(click)="clearFieldArrayControl(identificationFormGroup, 'addresses', 'contactName', i)">
<mat-icon>close</mat-icon>
</button>
<mat-hint align="end">
{{contactName.value.length}}/100.
</mat-hint>
</mat-form-field>
</div>
<div class="col-md-4">
<mat-form-field class="full-width">
<input matInput placeholder="E-Mail... " formControlName="contactEmail" #contactEmail
maxlength="100" required>
<button mat-button
*ngIf="(contactEmail.value && i == 0) || ((contactEmail.value && i > 0) && !copyValueAddress)"
[disabled]="contactEmail.disabled" matSuffix mat-icon-button aria-label="Clear"
(click)="clearFieldArrayControl(identificationFormGroup, 'addresses', 'contactEmail', i)">
<mat-icon>close</mat-icon>
</button>
<mat-hint align="end">
{{contactEmail.value.length}}/100.
</mat-hint>
<!-- input field error -->
<mat-error
*ngIf="identificationFormGroup.get('addresses')['controls'][i].value?.contactEmail?.invalid">
<span
[hidden]="!identificationFormGroup.get('addresses')['controls'][i].value?.contactEmail?.errors?.email">
Formato inválido para o campo.
</span>
</mat-error>
</mat-form-field>
</div>
<div class="col-md-4">
<mat-form-field class="full-width">
<input matInput placeholder="Telefone... " formControlName="contactPhone" #contactPhone
maxlength="100" [mask]="phoneMask" required>
<button mat-button
*ngIf="(contactPhone.value && i == 0) || ((contactPhone.value && i > 0) && !copyValueAddress)"
[disabled]="contactPhone.disabled" matSuffix mat-icon-button aria-label="Clear"
(click)="clearFieldArrayControl(identificationFormGroup, 'addresses', 'contactPhone', i)">
<mat-icon>close</mat-icon>
</button>
<mat-hint align="end">
{{contactPhone.value.length}}/100.
</mat-hint>
</mat-form-field>
</div>
<div class="col-md-12">
<mat-form-field class="full-width">
<textarea matInput placeholder="Observação..." rows="6" formControlName="observation"
#observation maxlength="500"></textarea>
<button mat-button
*ngIf="(observation.value && i == 0) || ((observation.value && i > 0) && !copyValueAddress)"
[disabled]="observation.disabled" matSuffix mat-icon-button aria-label="Clear"
(click)="clearFieldArrayControl(identificationFormGroup, 'addresses', 'observation', i)">
<mat-icon>close</mat-icon>
</button>
<mat-hint align="end">
{{observation.value.length}}/500.
</mat-hint>
</mat-form-field>
</div>
</div>
</div>
</mat-tab>
</mat-tab-group>
</mat-expansion-panel>
这是我当前使用的 valueChange 函数。
createAddress(i: number, data: CustomerAddressData = {
id: null,
companyId: null,
addressType: null,
city: null,
state: null,
country: null,
address: null,
addressNeighborhood: null,
addressZipCode: null,
addressNumber: null,
addressComplement: null,
contactName: null,
contactEmail: null,
contactPhone: null,
observation: null
}): FormGroup {
const formGroup = this.formBuilder.group({
id: [data.id === null ? 0 : data.id],
companyId: [data.companyId === null ? 0 : data.companyId],
addressType: [data.addressType === null ? i : 0],
city: [data.city, [Validators.required]],
state: [data.state, [Validators.required]],
country: [data.country, [Validators.required]],
address: [data.address, [Validators.required, Validators.maxLength(100)]],
addressNeighborhood: [data.addressNeighborhood, [Validators.required, Validators.maxLength(25)]],
addressZipCode: [data.addressZipCode, [Validators.required, Validators.minLength(8), Validators.minLength(8)]],
addressNumber: [data.addressNumber, [Validators.required, Validators.maxLength(7)]],
addressComplement: [data.addressComplement, [Validators.maxLength(100)]],
contactName: [data.contactName, [Validators.required, Validators.maxLength(100)]],
contactEmail: [data.contactEmail, [Validators.required, Validators.maxLength(100), Validators.email]],
contactPhone: [data.contactPhone, [Validators.required, Validators.maxLength(100)]],
observation: [data.observation, [Validators.maxLength(500)]],
});
formGroup.controls.addressZipCode.valueChanges
.pipe(
map(x => x !== undefined ? x : x !== null ? x : 0),
map(x => x !== null ? x : 0)
).subscribe();
formGroup.controls.addressZipCode.statusChanges
.pipe(
distinctUntilChanged(),
switchMap(status => status === 'VALID' ?
this.findZipCodeService.findZipCode(formGroup.controls.addressZipCode.value)
: empty()
),
catchError(err => throwError(err))
).subscribe(resp => {
if ('erro' in resp) {
this.toastAlertService.showError(
`CEP ${formGroup.controls.addressZipCode.value} informado não encontrado!`, 'Consulta de CEP.'
);
}
else {
this.auxiliaryDataService.getStates()
.subscribe(stateResult => {
if (resp['localidade'] !== undefined) {
const state = stateResult['data']?.filter(f => f.initialsCode === resp['uf']).map(m => m);
this.auxiliaryDataService.getCityByFilter(state ? state[0].id : 0, null, null, null, true)
.subscribe(s => {
const city = s['data']?.filter(f => f.ibgeCode.toString() === resp['ibge'].toString()).map(m => m);
const country = this.countryList.filter(f => f.initialsCode === 'BR').map(m => m);
formGroup.patchValue({
state: state[0],
city: city[0],
country: country[0],
address: resp['logradouro'],
addressNeighborhood: resp['bairro']
});
});
}
});
}
});
formGroup.controls.state.valueChanges
.pipe(
switchMap((value: number) => {
this.auxiliaryDataService.getCityByFilter(value ? value['id'] : 0, null, null, null, true)
.subscribe(s => {
this.cityList = s['data'];
}, (error) => {
console.log(error);
observableOf(null);
});
return of('');
}),
).subscribe();
formGroup.controls.country.valueChanges
.subscribe(value => {
this.phoneMask = '(00) 0000-0000 || (00) 00000-0000';
if ((value ? value['initialsCode'] : 'BR') !== 'BR') {
this.phoneMask = '';
}
this.auxiliaryDataService.getStateByFilter(value ? value['id'] : 0, null, null, null, true)
.subscribe(s => {
this.stateList = s['data'];
}, (error) => {
console.log(error);
observableOf(null);
});
return of('');
});
formGroup.controls.id.setValue(data.id === null ? 0 : data.id);
formGroup.controls.companyId.setValue(data.companyId === null ? 0 : data.companyId);
formGroup.controls.addressType.setValue(data.addressType === null ? i : 0);
formGroup.controls.city.setValue(data.city);
formGroup.controls.state.setValue(data.state);
formGroup.controls.country.setValue(data.country);
formGroup.controls.address.setValue(data.address);
formGroup.controls.addressNeighborhood.setValue(data.addressNeighborhood);
formGroup.controls.addressZipCode.setValue(data.addressZipCode);
formGroup.controls.addressNumber.setValue(data.addressNumber);
formGroup.controls.addressComplement.setValue(data.addressComplement);
formGroup.controls.contactName.setValue(data.contactName);
formGroup.controls.contactEmail.setValue(data.contactEmail);
formGroup.controls.contactPhone.setValue(data.contactPhone);
formGroup.controls.observation.setValue(data.observation);
return formGroup;
}
我需要将 Select 组件更改为自动完成。我无法在 3 个自动完成组件之间级联。