文档
Angular 学生列表组件
目标
创建典型的 Angular 组件:展示学生列表,支持搜索过滤和添加学生——涵盖 Component / Service / 双向绑定 / *ngFor / 管道。
完整代码
1. 创建项目并生成文件
ng new student-demo --routing --style scss
cd student-demo
ng g s services/student
2. src/app/services/student.service.ts
import { Injectable } from '@angular/core';
export interface Student {
id: number;
name: string;
major: string;
grade: number;
}
@Injectable({ providedIn: 'root' })
export class StudentService {
private students: Student[] = [
{ id: 1, name: '张三', major: '计算机科学', grade: 89 },
{ id: 2, name: '李四', major: '软件工程', grade: 92 },
{ id: 3, name: '王五', major: '人工智能', grade: 78 },
];
private nextId = 4;
getStudents(): Student[] {
return [...this.students];
}
addStudent(student: Omit<Student, 'id'>): void {
this.students.push({ ...student, id: this.nextId++ });
}
deleteStudent(id: number): void {
this.students = this.students.filter(s => s.id !== id);
}
}
3. src/app/app.component.ts
import { Component, OnInit } from '@angular/core';
import { StudentService, Student } from './services/student.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
students: Student[] = [];
searchTerm = '';
newStudent = { name: '', major: '', grade: null as number | null };
constructor(private studentService: StudentService) {}
ngOnInit() {
this.students = this.studentService.getStudents();
}
get filteredStudents(): Student[] {
return this.students.filter(s =>
s.name.includes(this.searchTerm) ||
s.major.includes(this.searchTerm)
);
}
addStudent() {
if (!this.newStudent.name || !this.newStudent.major || !this.newStudent.grade) return;
this.studentService.addStudent({ ...this.newStudent, grade: this.newStudent.grade! });
this.newStudent = { name: '', major: '', grade: null };
this.students = this.studentService.getStudents();
}
deleteStudent(id: number) {
this.studentService.deleteStudent(id);
this.students = this.studentService.getStudents();
}
}
4. src/app/app.component.html
<div class="container">
<h1>📋 学生管理系统</h1>
<!-- 搜索 -->
<input
type="text"
[(ngModel)]="searchTerm"
placeholder="搜索姓名或专业..."
class="search-input"
/>
<!-- 添加表单 -->
<div class="add-form">
<input [(ngModel)]="newStudent.name" placeholder="姓名" />
<input [(ngModel)]="newStudent.major" placeholder="专业" />
<input [(ngModel)]="newStudent.grade" placeholder="成绩" type="number" />
<button (click)="addStudent()">➕ 添加</button>
</div>
<!-- 学生列表 -->
<table>
<thead>
<tr>
<th>ID</th><th>姓名</th><th>专业</th><th>成绩</th><th>评级</th><th>操作</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let student of filteredStudents">
<td>{{ student.id }}</td>
<td>{{ student.name }}</td>
<td>{{ student.major }}</td>
<td>{{ student.grade }}</td>
<td>{{ student.grade >= 90 ? '优秀' : student.grade >= 80 ? '良好' : '及格' }}</td>
<td><button (click)="deleteStudent(student.id)">🗑️</button></td>
</tr>
</tbody>
</table>
</div>
5. src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, FormsModule],
bootstrap: [AppComponent]
})
export class AppModule { }
6. src/styles.scss
body { font-family: system-ui; background: #f5f5f5; margin: 0; padding: 20px; }
.container { max-width: 800px; margin: 0 auto; }
.search-input { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #ddd; border-radius: 6px; }
.add-form { display: flex; gap: 10px; margin: 10px 0;
input { flex: 1; padding: 8px; border: 1px solid #ddd; border-radius: 4px; }
button { padding: 8px 16px; background: #3b82f6; color: white; border: none; border-radius: 4px; cursor: pointer; }
}
table { width: 100%; border-collapse: collapse; background: white; border-radius: 8px; overflow: hidden;
th, td { padding: 12px; text-align: left; border-bottom: 1px solid #eee; }
th { background: #f8fafc; }
}
运行步骤
ng serve --open
预期输出
- 首页显示预置的 3 名学生
- 搜索框输入"计算机"过滤出张三
- 添加新学生后自动刷新列表
- 点击删除按钮移除学生