无法在Angular前端展示Laravel API的一对多关联薪资数据
问题:Angular无法展示Laravel一对多关联的Salary数据
我有一个对接Laravel API的Angular应用,Laravel中Employee与Salary为一对多关联,目前Employee基础数据能正常展示,但关联的Salary数据无法显示——尽管API返回的JSON里明确包含薪资信息。
Laravel 模型代码
Employee.php
protected $fillable = ['birth_date','first_name','last_name','gender','hire_date']; protected $primaryKey = 'emp_no'; public function salaries(): HasMany { return $this->hasMany(Salary::class, 'emp_no','emp_no'); }
Salary.php
protected $fillable = ['salary','from_date','to_date']; public function employee(): BelongsTo { return $this->belongsTo(Employee::class, 'emp_no'); }
Laravel 控制器与路由
EmployeeController.php
public function getEmployeeById($id) { $employee = Employee::with('titles','salaries')->find($id); if(is_null($employee)) { return response()->json(['message' => 'Employee Not Found'], 404); } return response()->json($employee::with('titles','salaries')->find($id), 200); }
API路由
//get specific employee Route::get('employee/{id}','App\Http\Controllers\EmployeeController@getEmployeeById');
Angular 代码
组件模板
<div class="basic-info"> <p>Employee Name : {{employee.first_name}}</p> <p>Date of Birth :</p> <p>Gender :</p> <p>Hire Date :</p> </div> <div class="salary-topic"> <h4><b>Salary Details</b></h4> </div> <div class="salary-details"> <table class="table"> <thead> <tr> <th scope="col">salary {{employee.salary}}</th> <th scope="col">From Date{{employee.from_date}}</th> <th scope="col">To Date{{employee.to_date}}</th> </tr> </thead> </table> </div>
data.service.ts
getEmployeeById(id: string){ return this.httpClient.get('http://127.0.0.1:8000/api/employee/'+id); }
employee-by-id.component.ts
getData() { this.dataService.getEmployeeById(this.id).subscribe(res => { // console.log(res); this.data = res; this.employee = this.data; }) }
问题现象
API返回的JSON包含完整薪资数据:
{ "emp_no": 1, "birth_date": "1983-10-05", "first_name": "David", "last_name": "Koner", "gender": "male", "hire_date": "2023-09-18", "created_at": null, "updated_at": null, "salaries": [ { "emp_no": 1, "salary": 27000, "from_date": "2023-09-22", "to_date": "2023-09-19", "created_at": "2023-10-09T08:17:26.000000Z", "updated_at": "2023-10-09T08:48:02.000000Z" } ] }
但Angular页面无法渲染出薪资信息。
解决方案
1. 修正Angular模板的数据访问逻辑
薪资数据存储在employee.salaries数组中,不是employee的直接属性,需要用*ngFor遍历数组展示每条记录:
修改后的组件模板:
<div class="basic-info"> <p>Employee Name : {{employee.first_name}}</p> <p>Date of Birth : {{employee.birth_date}}</p> <p>Gender : {{employee.gender}}</p> <p>Hire Date : {{employee.hire_date}}</p> </div> <div class="salary-topic"> <h4><b>Salary Details</b></h4> </div> <div class="salary-details"> <table class="table"> <thead> <tr> <th scope="col">Salary</th> <th scope="col">From Date</th> <th scope="col">To Date</th> </tr> </thead> <tbody> <!-- 遍历salaries数组,展示每条薪资数据 --> <tr *ngFor="let salary of employee?.salaries"> <td>{{salary.salary}}</td> <td>{{salary.from_date}}</td> <td>{{salary.to_date}}</td> </tr> </tbody> </table> </div>
- 使用
employee?.salaries可选链操作符,避免组件初始化时employee为undefined引发报错 - 表头改为静态文本,数据绑定移至tbody的遍历行中
2. (可选)定义Angular接口规范数据类型
创建employee.model.ts定义数据结构,避免属性访问错误:
export interface Salary { emp_no: number; salary: number; from_date: string; to_date: string; created_at: string; updated_at: string; } export interface Employee { emp_no: number; birth_date: string; first_name: string; last_name: string; gender: string; hire_date: string; created_at: string | null; updated_at: string | null; salaries: Salary[]; }
修改service和组件代码:
data.service.ts
import { Employee } from './employee.model'; getEmployeeById(id: string): Observable<Employee> { return this.httpClient.get<Employee>('http://127.0.0.1:8000/api/employee/'+id); }
employee-by-id.component.ts
import { Employee } from './employee.model'; employee: Employee | undefined; getData() { this.dataService.getEmployeeById(this.id).subscribe(res => { this.employee = res; }) }
3. 优化Laravel控制器代码(可选)
控制器中重复执行了查询逻辑,可简化为:
public function getEmployeeById($id) { $employee = Employee::with('titles','salaries')->find($id); if(is_null($employee)) { return response()->json(['message' => 'Employee Not Found'], 404); } return response()->json($employee, 200); }
内容的提问来源于stack exchange,提问作者Narakaya
相关产品推荐
相关产品推荐

