Angular 框架入门:模块、组件与服务
Angular 框架入门:模块、组件与服务
学习目标
完成本教程后,你将能够:
- 理解 Angular 的核心架构概念
- 使用 Angular CLI 创建和管理项目
- 编写并组织模块(Module)
- 创建和配置组件(Component)
- 实现服务(Service)并利用依赖注入(DI)共享数据与逻辑
前置知识
- 基础的 HTML、CSS 和 JavaScript(ES6+)
- 了解命令行的基本使用
- 已安装 Node.js(建议 v16 及以上)和 npm
环境准备与第一个项目
安装 Angular CLI
npm install -g @angular/cli
验证安装:
ng version
创建工作区
ng new my-first-app
按提示选择配置(如启用路由、样式格式等),推荐选择 SCSS 作为样式格式。
进入项目并启动开发服务器:
cd my-first-app
ng serve --open
浏览器访问 http://localhost:4200 即可看到默认页面。
Angular 模块(Module)
模块是 Angular 组织代码的基本单元。每个应用至少有一个根模块,通常名为 AppModule。
什么是 NgModule
@NgModule 装饰器将组件、指令、管道、服务等组织成一个内聚的功能块。模块可以延迟加载,也可以被其他模块导入。
根模块示例
打开 src/app/app.module.ts:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
@NgModule({
declarations: [ // 该模块拥有的组件、指令、管道
AppComponent
],
imports: [ // 导入其他模块
BrowserModule
],
providers: [], // 注册服务提供者
bootstrap: [AppComponent] // 启动的根组件
})
export class AppModule { }
特性模块
通常按功能拆分模块(如 UserModule、ProductModule)。使用 CLI 生成:
ng generate module user
生成的文件 user.module.ts:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
@NgModule({
declarations: [],
imports: [
CommonModule // 提供了 *ngIf、*ngFor 等常用指令
]
})
export class UserModule { }
之后可在根模块的 imports 中引入该特性模块。
组件(Component)
组件控制屏幕上的一小块区域,即视图。每个组件由三部分组成:类、模板、样式。
使用 CLI 生成组件
ng generate component user-profile
# 或简写 ng g c user-profile
自动在 app/user-profile/ 下生成四个文件:
user-profile.component.ts– 组件类user-profile.component.html– 模板user-profile.component.scss– 私有样式user-profile.component.spec.ts– 单元测试文件
并自动将组件声明到最近的模块 (declarations) 中。
组件元数据解析
import { Component } from '@angular/core';
@Component({
selector: 'app-user-profile', // HTML 标签名
templateUrl: './user-profile.component.html',
styleUrls: ['./user-profile.component.scss']
})
export class UserProfileComponent {
userName: string = '张三';
updateName() {
this.userName = '李四';
}
}
模板语法快速入门
插值绑定:{{ userName }}
属性绑定:<img [src]="imageUrl" />
事件绑定:<button (click)="updateName()">改名</button>
双向绑定:<input [(ngModel)]="userName" />(需在模块中导入 FormsModule)
组件的组合
在其它组件的模板中使用组件选择器即可嵌套:
<app-user-profile></app-user-profile>
服务与依赖注入(Service & DI)
服务是封装可复用业务逻辑、数据获取、共享状态的类。组件本身应保持精简,将逻辑委托给服务。
创建服务
ng generate service data
# 或 ng g s data
生成 data.service.ts:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root' // 该服务在根注入器中全局可用
})
export class DataService {
private items: string[] = ['学习 Angular', '写代码', '部署'];
getItems(): string[] {
return this.items;
}
addItem(item: string) {
this.items.push(item);
}
}
providedIn: 'root' 表示服务是单例的,整个应用共享同一个实例。这是树的摇树优化(tree-shaking)推荐的方式。
在组件中注入服务
import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';
@Component({
selector: 'app-todo',
template: `
<ul>
<li *ngFor="let item of items">{{ item }}</li>
</ul>
<input #newItem />
<button (click)="add(newItem.value); newItem.value=''">添加</button>
`
})
export class TodoComponent implements OnInit {
items: string[];
constructor(private dataService: DataService) { }
ngOnInit() {
this.items = this.dataService.getItems();
}
add(item: string) {
this.dataService.addItem(item);
}
}
组件构造函数中声明依赖,Angular 注入器负责提供服务的实例。这使得组件与服务的具体实现解耦,方便测试和维护。
服务作用域
除了 providedIn: 'root',还可以在模块或组件的 providers 数组中注册服务,控制其作用域和实例个数:
@Component({
selector: '...',
providers: [DataService] // 每个该组件实例都拥有独立的服务实例
})
整合示例:迷你待办事项应用
通过模块、组件、服务整合一个完整的可运行示例。
1. 生成服务
ng g s todo 并修改 todo.service.ts:
@Injectable({ providedIn: 'root' })
export class TodoService {
todos: { title: string; done: boolean }[] = [];
add(title: string) { this.todos.push({ title, done: false }); }
toggle(index: number) { this.todos[index].done = !this.todos[index].done; }
getAll() { return this.todos; }
}
2. 生成待办组件
ng g c todo-list
todo-list.component.ts:
import { Component, OnInit } from '@angular/core';
import { TodoService } from '../todo.service';
@Component({
selector: 'app-todo-list',
templateUrl: './todo-list.component.html',
styleUrls: ['./todo-list.component.scss']
})
export class TodoListComponent implements OnInit {
todos: any[];
constructor(private todoService: TodoService) {}
ngOnInit() {
this.todos = this.todoService.getAll();
}
add(title: string) {
this.todoService.add(title);
}
toggle(index: number) {
this.todoService.toggle(index);
}
}
todo-list.component.html:
<div>
<input #taskInput placeholder="输入任务" />
<button (click)="add(taskInput.value); taskInput.value=''">添加</button>
</div>
<ul>
<li *ngFor="let todo of todos; let i = index">
<span [class.done]="todo.done">{{ todo.title }}</span>
<button (click)="toggle(i)">
{{ todo.done ? '撤销' : '完成' }}
</button>
</li>
</ul>
3. 根组件中使用
将 <app-todo-list></app-todo-list> 加入 app.component.html,应用即可运行。
总结
- 模块(NgModule) 组织代码,声明组件、导入其他模块、注册服务提供者。
- 组件(Component) 定义视图与用户交互,通过模板和数据绑定实现动态 UI。
- 服务(Service) 封装可复用逻辑,通过依赖注入在组件之间共享数据与功能。
掌握了这三块核心,你已经可以开始构建功能完整、结构清晰的 Angular 应用。下一步可以深入学习路由、表单、HTTP 客户端和状态管理等内容。