我有 3 個國家、州、城市的下拉選單。我已經將 ng-select 模塊用于參考

如何使用 ng-select in angular 解決這些問題?請幫助和指導。謝謝。
編輯
模板代碼
<div class="col-sm-6">
<div class="form-group">
<label for="country">Country <b style="color: red">*</b></label><ng-select formControlName="country" (change)="onChangeCountry($event)" [ngClass]="{ 'error_border': submitted && f.country.errors }">
<ng-option *ngFor="let country of countryInfo" [value]="country.id">{{country.name}}</ng-option>
</ng-select>
<div *ngIf="submitted && f.country.errors" class="text-danger">
<div *ngIf="f.country.errors.required">Country is required</div>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="state">State <b style="color: red">*</b></label>
<ng-select formControlName="state" [ngClass]="{ 'error_border': submitted && f.state.errors }" (change)="onChangeState($event)">
<ng-option *ngFor="let state of stateInfo" [value]="state.id">{{state.name}}</ng-option>
</ng-select>
<div *ngIf="submitted && f.state.errors" class="text-danger">
<div *ngIf="f.state.errors.required">State is required</div>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="city">City <b style="color: red">*</b></label>
<ng-select formControlName="city" [ngClass]="{ 'error_border': submitted && f.city.errors }">
<ng-option *ngFor="let city of cityInfo" [value]="city.id">{{city.name}}</ng-option>
</ng-select>
<div *ngIf="submitted && f.city.errors" class="text-danger">
<div *ngIf="f.city.errors.required">City is required</div>
</div>
</div>
</div>
代碼
export class EditProfileComponent implements OnInit {
stateInfo: any[] = [];
countryInfo: any[] = [];
cityInfo: any[] = [];
dbCountryName = '';
dbCountryId = 0;
dbStateName = '';
dbStateId = 0;
dbCityName = '';
dbCityId = 0;
ngOnInit() {
this.form = this.formBuilder.group({
country: ['Select Country', Validators.required],
state: ['Select State', Validators.required],
city: ['Select City', Validators.required],
});
this.userService.getUserDetails(userDetails.id).subscribe((results) => {
if (results['status'] === true) {
this.dbStateName = results.data.state ? results.data.state : null;
this.dbStateId = results.data.state_id
? results.data.state_id
: null;
this.dbCityName = results.data.city ? results.data.city : null;
this.dbCityId = results.data.city_id ? results.data.city_id : null;
this.dbCountryName = results.data.country ? results.data.country : null;
this.dbCountryId = results.data.country_id
? results.data.country_id
: null;
this.cscService.getCountries().subscribe((result) => {
this.countryInfo = result.data;
this.form.patchValue({
country: this.dbCountryId
});
});
this.cscService.getStates(this.dbCountryId).subscribe((result) => {
this.stateInfo = result.data;
this.form.patchValue({
state: this.dbStateId
});
});
this.cscService
.getCities(this.dbStateId)
.subscribe((result) => {
this.cityInfo = result.data;
this.form.patchValue({
city: this.dbCityId
});
}
);
this.form.patchValue({
// country:
// results.data.country_id === null ? 'Select Country' : results.data.country_id,
// state:
// results.data.state_id === null ? 'Select State' : results.data.state_id,
// city: results.data.city_id === null ? 'Select City' : results.data.city_id,
});
}
});
}
getCountries() {
this.cscService.getCountries().subscribe((result) => {
this.countryInfo = result.data;
});
}
onChangeCountry(countryId: number) {
if (countryId) {
this.cscService.getStates(countryId).subscribe((result) => {
this.stateInfo = result.data;
this.cityInfo = null;
});
this.form.patchValue({
state: "Select State",
city: "Select City"
});
} else {
this.stateInfo = null;
this.cityInfo = null;
}
}
onChangeState(stateId: number) {
if (stateId) {
this.cscService
.getCities(stateId)
.subscribe((result) => (this.cityInfo = result.data));
this.form.patchValue({ city: "Select City" });
} else {
this.cityInfo = null;
}
}
}
國家資料回應

狀態資料回應 - 進入國家/地區選擇(我選擇了國家/地區 ID = 1)

城市資料回應 - 進入狀態選擇(我選擇了狀態 ID = 42)

uj5u.com熱心網友回復:
據我了解,您正在使用反應式表單來管理這些控制元件。如果這不是真的,請告訴我。
我建議的 HTML 模板與您的相似,但更簡單。我建議不要<ng-option>為選定的值/默認訊息添加單獨的訊息:
<ng-select formControlName="country" (change)="onChangeCountry($event)" style="width: 200px;">
<ng-option *ngFor="let country of countries" [value]="country.id">{{country.name}}</ng-option>
</ng-select>
<ng-select formControlName="state" (change)="onChangeState($event)" style="width: 200px;">
<ng-option *ngFor="let state of statesToShow" [value]="state.id">{{state.name}}</ng-option>
</ng-select>
<ng-select formControlName="city" (change)="onChangeCity($event)" style="width: 200px;">
<ng-option *ngFor="let city of citiesToShow" [value]="city.id">{{city.name}}</ng-option>
</ng-select>
我還包含了一個 TS 檔案,其中包含有關如何設定的作業示例
- 適當時的占位符訊息。
- 已選擇的值。請看
prefefinedValues()功能。
請注意,為了使 2. 按預期作業,元素的 ID 需要位于當前為控制元件選擇的資料源中(在我的示例中statesToShow或citiesToShow)。如果沒有,它將顯示為文本(可能是您正在經歷的)。
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, FormsModule } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'test2';
guestForm: FormGroup;
selectedCar: number = 0;
// this is the data source for the STATES drop-down (initially empty)
// => will be populated when a COUNTRY is selected
public statesToShow: Array<any> = [];
// this is the data source for the CITIES drop-down (initially empty)
// => will be populated when a STATE is selected
public citiesToShow: Array<any> = [];
// TEST data start
public countries = [
{ id: 1, name: 'Romania' },
{ id: 2, name: 'USA' },
{ id: 3, name: 'France' },
{ id: 4, name: 'Spain' },
];
public states = [
[],
[
{id: 1, name: "Cluj"},
{id: 2, name: "Valcea"},
{id: 3, name: "Sibiu"},
{id: 4, name: "Mures"},
],
[
{id: 5, name: "New York"},
{id: 6, name: "Oregon"},
{id: 7, name: "Arizona"},
{id: 8, name: "Texas"},
],
[
{id: 9, name: "Normandie"},
{id: 10, name: "Ile-de-France"},
{id: 11, name: "Grand Est"},
{id: 12, name: "Occitanie"},
],
[
{id: 13, name: "Alicante"},
{id: 14, name: "Valencia"},
{id: 15, name: "Sevilla"},
{id: 16, name: "Malaga"},
]
];
public cities = [
[],
[
{id: 1, name: "Cluj-Napoca"},
{id: 2, name: "Turda"},
{id: 3, name: "Huedin"},
],
[
{id: 4, name: "Ramnicul Valcea"},
{id: 5, name: "Horezu"},
{id: 6, name: "Olanesti"},
],
[],
[],
[
{id: 10, name: "New York city 1"},
{id: 11, name: "New York city 2"},
{id: 12, name: "New York city 3"},
],
[
{id: 13, name: "Oregon city 1"},
{id: 14, name: "Oregon city 2"},
{id: 15, name: "Oregon city 3"},
]
]
// TEST data end
private dbCountryId: number | null = null;
private dbStateId: number | null = null;
private dbCityId: number | null = null;
constructor(private _fb: FormBuilder) {
// add default placeholder messages for all the controls
this.guestForm = this._fb.group({
country: ['Please select country', null],
state: ['Please select state', null],
city: ['Please select city', null]
});
}
ngOnInit() {
}
onChangeCountry(value: number) {
// set the data source for the STATES drop-down
this.statesToShow = this.states[value];
// display placeholders for STATES and CITIES until the user
// selects the values
this.guestForm.patchValue({
state: "Please select state !",
city: "Please select city !"
});
}
onChangeState(value: number) {
// set the data source for the CITIES drop-down
this.citiesToShow = this.cities[value] ? this.cities[value] : [];
// display the placeholder until the user selects a new city
this.guestForm.patchValue({ city: "Please select city !" });
}
onChangeCity(value: number) {
console.log(value);
}
// example on how to correctly set preselected values
// in the controls
predefinedValues() {
// preselected values (MUST BE A VALID COMBINATION)
this.dbCountryId = 2;
this.dbStateId = 6;
this.dbCityId = 14;
// set the sources for STATES and CITIES drop-downs
this.statesToShow = this.states[this.dbCountryId];
this.citiesToShow = this.cities[this.dbStateId];
// set the preselected IDs as current value in all drop-downs
this.guestForm.patchValue({
country: this.dbCountryId,
state: this.dbStateId,
city: this.dbCityId
});
}
}
編輯:從服務器加載資料
當從服務器接收資料時,我們需要等待資訊到達,然后再對表單控制元件進行任何修補。該predefinedValues功能更改為:
predefinedValues() {
// read saved database values:
this._dataService.getSavedDatabaseValues()
.then(data => {
this.dbCountryId = data.dbCountryId;
this.dbStateId = data.dbStateId;
this.dbCityId = data.dbCityId;
// now that we have the saved IDs,
// load countries, states & cities for the saved data
this._dataService.getCountries()
.then(data => {
this.countriesToShow = data;
// now that the data binding to the control is complete
// we can do the patching
this.guestForm.patchValue({
country: this.dbCountryId
});
});
this._dataService.getStates(this.dbCountryId)
.then(data => {
this.statesToShow = data;
// now that the data binding to the control is complete
// we can do the patching
this.guestForm.patchValue({
state: this.dbStateId
});
});
this._dataService.getCities(this.dbStateId)
.then(data => {
this.citiesToShow = data;
// now that the data binding to the control is complete
// we can do the patching
this.guestForm.patchValue({
city: this.dbCityId
});
});
})
}
This function can be called directly in ngOnInit to load the previously saved data. Also, when one of the countries or states selections change, we need to load the data from the server.
onChangeCountry(value: number) {
// set the data source for the STATES drop-down
this._dataService.getStates(value)
.then(data => {
this.statesToShow = data;
});
// display placeholders for STATES and CITIES until the user
// selects the values
this.guestForm.patchValue({
state: "Please select state !",
city: "Please select city !"
});
}
Edit 2: In order to fix the issue with the required validation, I am suggesting a custom validator:
import {AbstractControl, ValidatorFn} from '@angular/forms';
export function selectIsRequired(): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } | null => {
console.log("validator:", control.value);
return control.value === 'Select Country'
|| control.value === 'Select State'
|| control.value === 'Select City'
|| isNaN(parseInt(control.value))
? {required: control.value} : null;
}
}
This will be applied on the select controls like this:
this.guestForm = this._fb.group({
country: ['Select country', selectIsRequired()],
state: ['Select state', selectIsRequired()],
city: ['Select city', selectIsRequired()]
});
uj5u.com熱心網友回復:
您應該嘗試以下選項中的專案
<ng-container ngFor="let country in countries"> \\ you can apply forloop like this and it will show default value
<ng-select
[items]="{{country.name}}"
formControlName="country"
bindLabel="label"
[multiple]="true"
placeholder="Select Country"
[(ngModel)]="selectedAttributes">
</ng-select>
</ng-container>
添加以下模塊
import { NgSelectModule } from '@ng-select/ng-select';
import { FormsModule } from '@angular/forms';
@NgModule({
imports: [
FormsModule,
NgSelectModule,
有關更多資訊,您可以查看此鏈接ng-select docs
uj5u.com熱心網友回復:
這個解決方案似乎有效。您需要控制器的 ngOnInit 函式中的 formControl 功能。希望這可以幫助。
在 html 檔案中,我有:
<div class="position">
<form [formGroup]="FormOne">
<ng-select
[formControlName]="city"
(change)="onChangeCity($event)"
placeholder="Select City"
><ng-option *ngFor="let city of cities" [value]="city.id">{{
city.name
}}</ng-option>
</ng-select>
</form>
</div>
例如,在控制器中,我有這個:
import { Component, OnInit } from '@angular/core';
import {
FormGroup,
Validators,
FormControl,
AbstractControl,
} from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
cities = [
{ id: 1, name: 'abc' },
{ id: 2, name: 'def' },
{ id: 3, name: 'ghi' },
{ id: 4, name: 'jkl' },
{ id: 5, name: 'mno' },
];
FormOne: FormGroup;
constructor() {}
ngOnInit() {
this.FormOne = new FormGroup({
city: new FormControl(null, Validators.required),
});
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/377688.html
