如何从数据库获取数据填充Angular表单的select下拉框?
动态从数据库填充Angular下拉选项的实现方案
开发CRUD应用时,需要从PostgreSQL的country表动态获取数据,填充Angular的<select>组件,替代手动编写<option>的方式,技术栈为Angular(前端)+ Django(后端)+ PostgreSQL(数据库)。以下是具体实现步骤:
一、Django后端调整
1. 修正Country模型的字符串展示方法
原models.py中Country模型的__str__方法引用了不存在的name字段,需修正为对应字段country:
from django.db import models class Country(models.Model): country = models.CharField(max_length=50) def __str__(self): return self.country # 修正为自身country字段 class Tax(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=255) country = models.ForeignKey(Country, on_delete=models.CASCADE) taxtype = models.CharField(max_length=10) zone = models.CharField(max_length=255, null=True, blank=True) ward = models.CharField(max_length=255, null=True, blank=True) status = models.CharField(max_length=255, null=True, blank=True) def __str__(self): return self.name
2. 创建Country序列化器
在应用的serializers.py中添加Country的序列化类,用于API数据转换:
from rest_framework import serializers from .models import Tax, Country class CountrySerializer(serializers.ModelSerializer): class Meta: model = Country fields = ['id', 'country'] class TaxSerializer(serializers.ModelSerializer): class Meta: model = Tax fields = '__all__'
3. 配置Country视图与API路由
在应用的views.py中添加Country的视图集:
from rest_framework import viewsets from .models import Tax, Country from .serializers import TaxSerializer, CountrySerializer class CountryViewSet(viewsets.ModelViewSet): queryset = Country.objects.all() serializer_class = CountrySerializer class TaxViewSet(viewsets.ModelViewSet): queryset = Tax.objects.all() serializer_class = TaxSerializer
在项目根urls.py中添加国家列表的API路由:
from django.contrib import admin from django.urls import path, include from rest_framework import routers from taxapp.views import TaxViewSet, CountryViewSet router = routers.DefaultRouter() router.register(r'taxapp', TaxViewSet) router.register(r'countries', CountryViewSet) # 新增国家数据路由 urlpatterns = [ path('admin/', admin.site.urls), path('api/', include(router.urls)), ]
二、Angular前端调整
1. 创建Country数据接口
在Angular项目中新建country.ts文件,定义国家数据结构:
export interface Country { id: number; country: string; }
2. 修正TaxService服务的国家数据获取方法
更新app.service.ts,指定正确的国家API地址,调整返回类型为Country数组:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { Tax } from './Tax'; import { Country } from './country'; @Injectable({ providedIn: 'root' }) export class TaxService { private taxUrl: string = 'http://localhost:8000/api/taxapp/'; private countryUrl: string = 'http://localhost:8000/api/countries/'; constructor(private http: HttpClient) { } // 保留原有Tax相关方法 getCountries(): Observable<Country[]> { return this.http.get<Country[]>(this.countryUrl); } }
3. 组件内加载国家数据并绑定表单
更新add-tax.component.ts,在组件初始化时获取国家列表,存储后用于模板渲染:
import { Component, OnInit } from '@angular/core'; import { TaxService } from 'src/app/app.service'; import { FormControl, FormGroup, Validators } from '@angular/forms'; import { Router } from '@angular/router'; import { Country } from 'src/app/country'; @Component({ selector: 'app-add-tax', templateUrl: './add-tax.component.html', styleUrls: ['./add-tax.component.css'] }) export class AddTaxComponent implements OnInit { countries: Country[] = []; constructor(private service: TaxService, private router: Router) { } ngOnInit(): void { this.loadCountries(); } loadCountries(): void { this.service.getCountries().subscribe(data => { this.countries = data; }); } form = new FormGroup({ name: new FormControl('', Validators.required), country: new FormControl('', Validators.required), taxtype: new FormControl('', Validators.required), zone: new FormControl('', Validators.required), ward: new FormControl('', Validators.required), status: new FormControl('', Validators.required), }); addTax() { this.service.addTax(this.form.value).subscribe(() => { this.router.navigate(['/']); }); } }
4. 模板中动态生成下拉选项
更新add-tax.component.html,使用*ngFor循环生成动态选项:
<div class="col form-group"> <label for="country" class="form-label">Country Name</label> <select class="form-select" formControlName="country" name="country" id="country"> <option value="" disabled selected>Select a country</option> <option *ngFor="let country of countries" [value]="country.id">{{ country.country }}</option> </select> </div>
若使用Angular Material组件,可替换为:
<div class="col form-group"> <mat-form-field> <mat-label>Country Name</mat-label> <mat-select formControlName="country" name="country" id="country"> <mat-option value="" disabled selected>Select a country</mat-option> <mat-option *ngFor="let country of countries" [value]="country.id">{{ country.country }}</mat-option> </mat-select> </mat-form-field> </div>
内容的提问来源于stack exchange,提问作者Purushottam Nawale
相关产品推荐
相关产品推荐

