Skip to Content
🚀 欢迎来到前端学习指南!这是一份从零基础到专家的完整学习路径
⚛️ 第二部分:框架篇09. Angular框架和TypeScript

09. Angular框架和TypeScript

📋 目录

Angular架构深入

Angular是一个完整的企业级前端框架,提供了从开发到部署的完整解决方案,特别适合大型复杂应用的开发。

Angular核心概念

核心构建块对比

构建块作用装饰器使用场景
ComponentUI组件@Component页面元素、可复用组件
Service业务逻辑@Injectable数据处理、API调用
DirectiveDOM操作@Directive行为增强、DOM修改
Pipe数据转换@Pipe数据格式化、过滤
Module功能模块@NgModule功能组织、依赖管理

组件示例

// 1. 基础组件 @Component({ selector: 'app-user-card', template: ` <div class="user-card" [class.active]="isActive"> <img [src]="user.avatar" [alt]="user.name"> <h3>{{ user.name }}</h3> <p>{{ user.email }}</p> <button (click)="onEdit()" [disabled]="!canEdit">编辑</button> <button (click)="onDelete()" class="danger">删除</button> </div> `, styleUrls: ['./user-card.component.scss'] }) export class UserCardComponent implements OnInit, OnDestroy { @Input() user!: User; @Input() canEdit: boolean = true; @Input() isActive: boolean = false; @Output() edit = new EventEmitter<User>(); @Output() delete = new EventEmitter<string>(); private destroy$ = new Subject<void>(); ngOnInit(): void { console.log('UserCard component initialized'); } ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); } onEdit(): void { this.edit.emit(this.user); } onDelete(): void { this.delete.emit(this.user.id); } }

服务示例

// 2. 数据服务 export interface User { id: string; name: string; email: string; avatar: string; role: 'admin' | 'user'; } @Injectable({ providedIn: 'root' }) export class UserService { private readonly apiUrl = '/api/users'; private usersSubject = new BehaviorSubject<User[]>([]); public users$ = this.usersSubject.asObservable(); constructor(private http: HttpClient) {} getUsers(): Observable<User[]> { return this.http.get<User[]>(this.apiUrl).pipe( tap(users => this.usersSubject.next(users)), catchError(this.handleError) ); } createUser(user: Omit<User, 'id'>): Observable<User> { return this.http.post<User>(this.apiUrl, user).pipe( tap(newUser => { const currentUsers = this.usersSubject.value; this.usersSubject.next([...currentUsers, newUser]); }), catchError(this.handleError) ); } private handleError(error: HttpErrorResponse): Observable<never> { const errorMessage = error.error instanceof ErrorEvent ? `客户端错误: ${error.error.message}` : `服务端错误: ${error.status} - ${error.message}`; console.error(errorMessage); return throwError(() => new Error(errorMessage)); } }

指令和管道示例

// 3. 自定义指令 @Directive({ selector: '[appHighlight]' }) export class HighlightDirective { @Input() appHighlight = ''; @Input() defaultColor = 'yellow'; constructor(private el: ElementRef) {} @HostListener('mouseenter') onMouseEnter() { this.highlight(this.appHighlight || this.defaultColor); } @HostListener('mouseleave') onMouseLeave() { this.highlight(''); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; } } // 4. 自定义管道 @Pipe({ name: 'truncate', pure: true }) export class TruncatePipe implements PipeTransform { transform(value: string, limit: number = 50, trail: string = '...'): string { if (!value) return ''; return value.length > limit ? value.substring(0, limit) + trail : value; } } // 使用:<p>{{ longText | truncate:100:'...' }}</p>

模块系统

模块类型对比

模块类型作用特点使用场景
特性模块组织相关功能包含组件、服务、路由用户管理、订单管理
共享模块共享通用组件导出常用组件和指令UI组件库、工具函数
核心模块全局单例服务只导入一次认证、拦截器
懒加载模块按需加载减少初始包大小大型功能模块

模块示例

// 1. 特性模块 @NgModule({ declarations: [ UserListComponent, UserCardComponent, UserFormComponent, TruncatePipe, HighlightDirective ], imports: [ CommonModule, ReactiveFormsModule, RouterModule.forChild([ { path: '', component: UserListComponent }, { path: 'create', component: UserFormComponent }, { path: ':id/edit', component: UserFormComponent } ]) ], providers: [UserService], exports: [UserCardComponent, TruncatePipe] }) export class UserModule {} // 2. 共享模块 @NgModule({ declarations: [ LoadingSpinnerComponent, ConfirmDialogComponent, ToastComponent ], imports: [CommonModule, MaterialModule], exports: [ CommonModule, MaterialModule, LoadingSpinnerComponent, ConfirmDialogComponent, ToastComponent ] }) export class SharedModule {} // 3. 核心模块(单例) @NgModule({ providers: [ AuthService, { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true } ] }) export class CoreModule { constructor(@Optional() @SkipSelf() parentModule: CoreModule) { if (parentModule) { throw new Error('CoreModule已经加载,只能在AppModule中导入一次'); } } }

模块最佳实践

  • 特性模块:按业务功能组织,包含相关的组件、服务和路由
  • 共享模块:导出通用组件和第三方模块,避免重复导入
  • 核心模块:包含全局单例服务,确保只导入一次
  • 懒加载:大型功能模块使用懒加载,提升应用启动性能

TypeScript在Angular中的应用

高级类型系统

⚠️

TypeScript的强类型系统是Angular的核心优势之一,能够在编译时发现错误,提高代码质量。

TypeScript特性在Angular中的应用

特性用途优势示例
接口定义数据结构约束编译时类型检查interface User
泛型类型参数化代码复用,类型安全ApiResponse<T>
联合类型多种可能类型精确的类型约束'admin' | 'user'
映射类型类型转换基于现有类型生成新类型Partial<T>
类型守卫运行时类型检查类型安全的类型缩窄obj is User

基础类型定义

// 1. 接口和类型定义 export interface ApiResponse<T> { data: T; message: string; success: boolean; timestamp: number; } export interface PaginatedResponse<T> extends ApiResponse<T[]> { pagination: { page: number; limit: number; total: number; totalPages: number; }; } export type UserRole = 'admin' | 'moderator' | 'user'; export type UserStatus = 'active' | 'inactive' | 'pending'; export interface User { id: string; name: string; email: string; role: UserRole; status: UserStatus; createdAt: Date; updatedAt: Date; profile?: UserProfile; }

泛型服务

// 2. 泛型API服务 @Injectable({ providedIn: 'root' }) export class ApiService { constructor(private http: HttpClient) {} get<T>(url: string): Observable<ApiResponse<T>> { return this.http.get<ApiResponse<T>>(url); } post<T, U = any>(url: string, data: U): Observable<ApiResponse<T>> { return this.http.post<ApiResponse<T>>(url, data); } getPaginated<T>( url: string, params: { page: number; limit: number } ): Observable<PaginatedResponse<T>> { const httpParams = new HttpParams() .set('page', params.page.toString()) .set('limit', params.limit.toString()); return this.http.get<PaginatedResponse<T>>(url, { params: httpParams }); } }

实用类型和类型守卫

// 3. 实用类型示例 export type CreateUserDto = Omit<User, 'id' | 'createdAt' | 'updatedAt'>; export type UpdateUserDto = Partial<Pick<User, 'name' | 'email' | 'role' | 'status'>>; export type UserSummary = Pick<User, 'id' | 'name' | 'email' | 'role'>; // 4. 类型守卫 export function isUser(obj: any): obj is User { return obj && typeof obj.id === 'string' && typeof obj.name === 'string' && typeof obj.email === 'string' && ['admin', 'moderator', 'user'].includes(obj.role); } // 5. 使用类型守卫 @Component({ selector: 'app-user-detail', template: ` <div *ngIf="user"> <h2>{{ user.name }}</h2> <p>{{ user.email }}</p> </div> ` }) export class UserDetailComponent { user: User | null = null; loadUser(data: unknown): void { if (isUser(data)) { this.user = data; // TypeScript知道这里data是User类型 } else { console.error('Invalid user data:', data); } } }

TypeScript最佳实践

  • 严格模式:启用strict: true获得最佳类型检查
  • 接口优于类型别名:对于对象结构使用interface
  • 泛型约束:使用extends约束泛型参数
  • 类型守卫:运行时类型检查确保类型安全
  • 实用类型:充分利用内置实用类型简化类型定义

依赖注入系统

高级依赖注入

依赖注入提供者类型

提供者类型语法用途示例
类提供者useClass提供类实例{ provide: Service, useClass: MockService }
值提供者useValue提供静态值{ provide: CONFIG, useValue: config }
工厂提供者useFactory动态创建实例{ provide: Logger, useFactory: createLogger }
别名提供者useExisting引用现有提供者{ provide: NewService, useExisting: OldService }

注入令牌和配置

// 1. 注入令牌 import { InjectionToken } from '@angular/core'; export const API_CONFIG = new InjectionToken<ApiConfig>('api.config'); export const FEATURE_FLAGS = new InjectionToken<FeatureFlags>('feature.flags'); export interface ApiConfig { baseUrl: string; timeout: number; retryAttempts: number; } export interface FeatureFlags { enableNewUI: boolean; enableAnalytics: boolean; enableBetaFeatures: boolean; } // 2. 工厂提供者 export function createApiService(http: HttpClient, config: ApiConfig): ApiService { return new ApiService(http, config); } export function createLogger(isDevelopment: boolean): Logger { return isDevelopment ? new ConsoleLogger() : new RemoteLogger(); }

模块配置示例

// 3. 模块配置 @NgModule({ providers: [ { provide: API_CONFIG, useValue: { baseUrl: 'https://api.example.com', timeout: 5000, retryAttempts: 3 } }, { provide: FEATURE_FLAGS, useFactory: () => ({ enableNewUI: environment.production, enableAnalytics: true, enableBetaFeatures: !environment.production }) }, { provide: ApiService, useFactory: createApiService, deps: [HttpClient, API_CONFIG] } ] }) export class AppModule {}

注入装饰器

// 4. 注入装饰器使用 @Component({ selector: 'app-user-list', providers: [ { provide: UserService, useClass: CachedUserService } ] }) export class UserListComponent { constructor( private userService: UserService, // 使用CachedUserService @Inject(FEATURE_FLAGS) private featureFlags: FeatureFlags, @Optional() private analytics: AnalyticsService, // 可选依赖 @Self() private localService: LocalService // 只在当前注入器查找 ) {} }

依赖注入最佳实践

  • 使用接口:定义服务契约,便于测试和替换
  • 注入令牌:为非类依赖提供类型安全的注入
  • 工厂函数:复杂对象创建逻辑
  • 层级注入:合理利用注入器层级,避免不必要的单例
  • 可选依赖:使用@Optional()处理可选服务

RxJS响应式编程

Observable模式深入

RxJS是Angular的核心依赖,掌握响应式编程对于构建高质量的Angular应用至关重要。

常用RxJS操作符

操作符类型操作符作用使用场景
创建of, from, interval创建Observable数据源创建
转换map, switchMap, mergeMap数据转换数据处理、API调用
过滤filter, debounceTime, distinctUntilChanged数据过滤搜索、去重
组合combineLatest, merge, zip流组合状态管理
错误处理catchError, retry, retryWhen错误处理异常恢复

搜索服务示例

// 1. 搜索服务 @Injectable({ providedIn: 'root' }) export class SearchService { private searchTerms = new Subject<string>(); // 搜索结果流 public searchResults$ = this.searchTerms.pipe( debounceTime(300), // 防抖 distinctUntilChanged(), // 去重 filter(term => term.length >= 2), // 过滤短查询 switchMap(term => this.apiService.search(term).pipe( catchError(error => { console.error('搜索错误:', error); return of([]); // 返回空数组作为默认值 }) ) ), shareReplay(1) // 缓存最新结果 ); search(term: string): void { this.searchTerms.next(term); } }

状态管理服务

// 2. 状态管理服务 @Injectable({ providedIn: 'root' }) export class UserStateService { private usersSubject = new BehaviorSubject<User[]>([]); private loadingSubject = new BehaviorSubject<boolean>(false); private errorSubject = new BehaviorSubject<string | null>(null); public users$ = this.usersSubject.asObservable(); public loading$ = this.loadingSubject.asObservable(); public error$ = this.errorSubject.asObservable(); // 组合状态 public state$ = combineLatest([ this.users$, this.loading$, this.error$ ]).pipe( map(([users, loading, error]) => ({ users, loading, error, hasUsers: users.length > 0, isEmpty: users.length === 0 && !loading && !error })) ); loadUsers(): void { this.loadingSubject.next(true); this.errorSubject.next(null); this.userService.getUsers().pipe( finalize(() => this.loadingSubject.next(false)) ).subscribe({ next: users => this.usersSubject.next(users), error: error => this.errorSubject.next(error.message) }); } }

RxJS最佳实践

  • 内存泄漏防护:使用takeUntilasync管道自动取消订阅
  • 错误处理:使用catchError处理错误,避免流中断
  • 性能优化:使用shareReplay缓存结果,避免重复请求
  • 操作符选择switchMap用于搜索,mergeMap用于并发请求
  • 状态管理:使用BehaviorSubject管理组件状态

Angular企业级开发

高级RxJS模式

// 1. 自定义操作符 export function retryWithBackoff(maxRetries: number = 3, baseDelay: number = 1000) { return <T>(source: Observable<T>) => source.pipe( retryWhen(errors => errors.pipe( scan((retryCount, error) => { if (retryCount >= maxRetries) { throw error; } return retryCount + 1; }, 0), delay(baseDelay), tap(retryCount => console.log(`重试第 ${retryCount} 次`)) ) ) ); } // 2. 缓存操作符 export function cacheWithExpiry<T>(ttl: number = 5000) { return (source: Observable<T>) => { let cache: { value: T; timestamp: number } | null = null; return new Observable<T>(observer => { if (cache && Date.now() - cache.timestamp < ttl) { observer.next(cache.value); observer.complete(); return; } return source.subscribe({ next: value => { cache = { value, timestamp: Date.now() }; observer.next(value); }, error: error => observer.error(error), complete: () => observer.complete() }); }); }; } // 使用自定义操作符 @Injectable({ providedIn: 'root' }) export class DataService { getData(): Observable<any> { return this.http.get('/api/data').pipe( retryWithBackoff(3, 1000), cacheWithExpiry(10000), catchError(error => { console.error('获取数据失败:', error); return throwError(() => error); }) ); } } // 4. 响应式表单 @Component({ selector: 'app-user-form', template: ` <form [formGroup]="userForm" (ngSubmit)="onSubmit()"> <div class="form-group"> <label for="name">姓名</label> <input id="name" type="text" formControlName="name" [class.invalid]="nameControl.invalid && nameControl.touched"> <div *ngIf="nameControl.invalid && nameControl.touched" class="error"> <span *ngIf="nameControl.errors?.['required']">姓名是必填项</span> <span *ngIf="nameControl.errors?.['minlength']">姓名至少2个字符</span> </div> </div> <div class="form-group"> <label for="email">邮箱</label> <input id="email" type="email" formControlName="email" [class.invalid]="emailControl.invalid && emailControl.touched"> <div *ngIf="emailControl.invalid && emailControl.touched" class="error"> <span *ngIf="emailControl.errors?.['required']">邮箱是必填项</span> <span *ngIf="emailControl.errors?.['email']">邮箱格式不正确</span> <span *ngIf="emailControl.errors?.['emailTaken']">邮箱已被使用</span> </div> </div> <button type="submit" [disabled]="userForm.invalid || submitting"> {{ submitting ? '提交中...' : '提交' }} </button> </form> ` }) export class UserFormComponent implements OnInit, OnDestroy { userForm!: FormGroup; submitting = false; private destroy$ = new Subject<void>(); constructor( private fb: FormBuilder, private userService: UserService ) {} ngOnInit(): void { this.createForm(); this.setupFormValidation(); } ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); } get nameControl() { return this.userForm.get('name')!; } get emailControl() { return this.userForm.get('email')!; } private createForm(): void { this.userForm = this.fb.group({ name: ['', [Validators.required, Validators.minLength(2)]], email: ['', [Validators.required, Validators.email], [this.emailValidator.bind(this)]] }); } private setupFormValidation(): void { // 实时验证 this.userForm.valueChanges.pipe( debounceTime(300), takeUntil(this.destroy$) ).subscribe(value => { console.log('表单值变化:', value); }); // 邮箱字段变化时的特殊处理 this.emailControl.valueChanges.pipe( debounceTime(500), distinctUntilChanged(), takeUntil(this.destroy$) ).subscribe(email => { if (email && this.emailControl.valid) { console.log('邮箱验证通过:', email); } }); } private emailValidator(control: AbstractControl): Observable<ValidationErrors | null> { if (!control.value) { return of(null); } return this.userService.checkEmailExists(control.value).pipe( map(exists => exists ? { emailTaken: true } : null), catchError(() => of(null)) ); } onSubmit(): void { if (this.userForm.valid) { this.submitting = true; this.userService.createUser(this.userForm.value).pipe( finalize(() => this.submitting = false), takeUntil(this.destroy$) ).subscribe({ next: user => { console.log('用户创建成功:', user); this.userForm.reset(); }, error: error => { console.error('用户创建失败:', error); } }); } } }

企业级架构模式

// 1. 特性模块架构 // shared/shared.module.ts @NgModule({ declarations: [ LoadingComponent, ConfirmDialogComponent, DataTableComponent ], imports: [ CommonModule, MaterialModule, ReactiveFormsModule ], exports: [ LoadingComponent, ConfirmDialogComponent, DataTableComponent, MaterialModule, ReactiveFormsModule ] }) export class SharedModule {} // core/core.module.ts @NgModule({ providers: [ AuthService, ErrorHandlerService, LoggerService, { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true } ] }) export class CoreModule { constructor(@Optional() @SkipSelf() parentModule: CoreModule) { if (parentModule) { throw new Error('CoreModule已经加载,只能在AppModule中导入一次'); } } } // features/user/user.module.ts @NgModule({ declarations: [ UserListComponent, UserDetailComponent, UserFormComponent ], imports: [ CommonModule, SharedModule, UserRoutingModule ] }) export class UserModule {} // 2. 状态管理架构 // store/user/user.state.ts export interface UserState { users: User[]; selectedUser: User | null; loading: boolean; error: string | null; } export const initialUserState: UserState = { users: [], selectedUser: null, loading: false, error: null }; // store/user/user.actions.ts export const UserActions = createActionGroup({ source: 'User', events: { 'Load Users': emptyProps(), 'Load Users Success': props<{ users: User[] }>(), 'Load Users Failure': props<{ error: string }>(), 'Select User': props<{ userId: string }>(), 'Create User': props<{ user: Partial<User> }>(), 'Update User': props<{ user: User }>(), 'Delete User': props<{ userId: string }>() } }); // store/user/user.reducer.ts export const userReducer = createReducer( initialUserState, on(UserActions.loadUsers, (state) => ({ ...state, loading: true, error: null })), on(UserActions.loadUsersSuccess, (state, { users }) => ({ ...state, users, loading: false })), on(UserActions.loadUsersFailure, (state, { error }) => ({ ...state, loading: false, error })), on(UserActions.selectUser, (state, { userId }) => ({ ...state, selectedUser: state.users.find(user => user.id === userId) || null })) ); // store/user/user.effects.ts @Injectable() export class UserEffects { loadUsers$ = createEffect(() => this.actions$.pipe( ofType(UserActions.loadUsers), switchMap(() => this.userService.getUsers().pipe( map(users => UserActions.loadUsersSuccess({ users })), catchError(error => of(UserActions.loadUsersFailure({ error: error.message }))) ) ) ) ); createUser$ = createEffect(() => this.actions$.pipe( ofType(UserActions.createUser), switchMap(({ user }) => this.userService.createUser(user).pipe( map(() => UserActions.loadUsers()), catchError(error => of(UserActions.loadUsersFailure({ error: error.message }))) ) ) ) ); constructor( private actions$: Actions, private userService: UserService ) {} } // 3. 企业级表单管理 @Injectable({ providedIn: 'root' }) export class FormBuilderService { createUserForm(): FormGroup { return this.fb.group({ personalInfo: this.fb.group({ firstName: ['', [Validators.required, Validators.minLength(2)]], lastName: ['', [Validators.required, Validators.minLength(2)]], email: ['', [Validators.required, Validators.email]], phone: ['', [Validators.pattern(/^\d{10,11}$/)]] }), address: this.fb.group({ street: ['', Validators.required], city: ['', Validators.required], state: ['', Validators.required], zipCode: ['', [Validators.required, Validators.pattern(/^\d{5}$/)]] }), preferences: this.fb.group({ newsletter: [false], notifications: [true], theme: ['light'] }) }); } constructor(private fb: FormBuilder) {} } // 4. 权限管理系统 @Injectable({ providedIn: 'root' }) export class PermissionService { private permissions$ = new BehaviorSubject<string[]>([]); hasPermission(permission: string): Observable<boolean> { return this.permissions$.pipe( map(permissions => permissions.includes(permission)) ); } hasAnyPermission(permissions: string[]): Observable<boolean> { return this.permissions$.pipe( map(userPermissions => permissions.some(permission => userPermissions.includes(permission)) ) ); } setPermissions(permissions: string[]): void { this.permissions$.next(permissions); } } @Directive({ selector: '[appHasPermission]' }) export class HasPermissionDirective implements OnInit, OnDestroy { @Input() appHasPermission!: string; private destroy$ = new Subject<void>(); constructor( private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef, private permissionService: PermissionService ) {} ngOnInit(): void { this.permissionService.hasPermission(this.appHasPermission).pipe( takeUntil(this.destroy$) ).subscribe(hasPermission => { if (hasPermission) { this.viewContainer.createEmbeddedView(this.templateRef); } else { this.viewContainer.clear(); } }); } ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); } }

性能优化和最佳实践

⚠️

Angular应用的性能优化需要从多个维度考虑,包括变更检测、懒加载、预加载策略等。

变更检测优化

// 1. OnPush变更检测策略 @Component({ selector: 'app-user-card', template: ` <div class="user-card"> <h3>{{ user.name }}</h3> <p>{{ user.email }}</p> <button (click)="onEdit()">编辑</button> </div> `, changeDetection: ChangeDetectionStrategy.OnPush }) export class UserCardComponent { @Input() user!: User; @Output() edit = new EventEmitter<User>(); constructor(private cdr: ChangeDetectorRef) {} onEdit(): void { this.edit.emit(this.user); } // 手动触发变更检测 updateUser(user: User): void { this.user = user; this.cdr.markForCheck(); } } // 2. TrackBy函数优化 @Component({ selector: 'app-user-list', template: ` <div class="user-list"> <app-user-card *ngFor="let user of users; trackBy: trackByUserId" [user]="user" (edit)="onEditUser($event)"> </app-user-card> </div> ` }) export class UserListComponent { @Input() users: User[] = []; trackByUserId(index: number, user: User): string { return user.id; } onEditUser(user: User): void { // 编辑用户逻辑 } } // 3. 异步管道优化 @Component({ selector: 'app-dashboard', template: ` <div class="dashboard"> <div *ngIf="users$ | async as users"> <app-user-list [users]="users"></app-user-list> </div> <div *ngIf="loading$ | async" class="loading"> 加载中... </div> </div> ` }) export class DashboardComponent { users$ = this.store.select(selectUsers); loading$ = this.store.select(selectUsersLoading); constructor(private store: Store) {} } // 4. 虚拟滚动 @Component({ selector: 'app-virtual-list', template: ` <cdk-virtual-scroll-viewport itemSize="50" class="viewport"> <div *cdkVirtualFor="let item of items; trackBy: trackByFn"> {{ item.name }} </div> </cdk-virtual-scroll-viewport> `, styles: [` .viewport { height: 400px; width: 100%; } `] }) export class VirtualListComponent { @Input() items: any[] = []; trackByFn(index: number, item: any): any { return item.id; } }

懒加载和预加载策略

// 1. 路由懒加载 const routes: Routes = [ { path: 'users', loadChildren: () => import('./features/users/users.module').then(m => m.UsersModule) }, { path: 'products', loadChildren: () => import('./features/products/products.module').then(m => m.ProductsModule) }, { path: 'orders', loadChildren: () => import('./features/orders/orders.module').then(m => m.OrdersModule) } ]; // 2. 自定义预加载策略 @Injectable() export class CustomPreloadingStrategy implements PreloadingStrategy { preload(route: Route, load: () => Observable<any>): Observable<any> { // 只预加载标记为preload的路由 if (route.data && route.data['preload']) { console.log('预加载路由:', route.path); return load(); } return of(null); } } // 路由配置 const routes: Routes = [ { path: 'users', loadChildren: () => import('./features/users/users.module').then(m => m.UsersModule), data: { preload: true } }, { path: 'admin', loadChildren: () => import('./features/admin/admin.module').then(m => m.AdminModule), data: { preload: false } } ]; @NgModule({ imports: [RouterModule.forRoot(routes, { preloadingStrategy: CustomPreloadingStrategy })], providers: [CustomPreloadingStrategy] }) export class AppRoutingModule {} // 3. 组件懒加载 @Component({ selector: 'app-lazy-component', template: ` <div> <button (click)="loadComponent()" *ngIf="!componentLoaded"> 加载组件 </button> <ng-container #dynamicComponent></ng-container> </div> ` }) export class LazyComponentComponent { @ViewChild('dynamicComponent', { read: ViewContainerRef }) dynamicComponent!: ViewContainerRef; componentLoaded = false; constructor(private componentFactoryResolver: ComponentFactoryResolver) {} async loadComponent(): Promise<void> { const { HeavyComponent } = await import('./heavy/heavy.component'); const componentFactory = this.componentFactoryResolver.resolveComponentFactory(HeavyComponent); this.dynamicComponent.createComponent(componentFactory); this.componentLoaded = true; } }

内存管理和性能监控

// 1. 内存泄漏防护 @Component({ selector: 'app-memory-safe', template: `<div>{{ data$ | async }}</div>` }) export class MemorySafeComponent implements OnInit, OnDestroy { data$!: Observable<any>; private destroy$ = new Subject<void>(); ngOnInit(): void { // 使用takeUntil防止内存泄漏 this.data$ = this.dataService.getData().pipe( takeUntil(this.destroy$) ); // 定时器也需要清理 interval(1000).pipe( takeUntil(this.destroy$) ).subscribe(value => { console.log('定时器值:', value); }); } ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); } } // 2. 性能监控服务 @Injectable({ providedIn: 'root' }) export class PerformanceMonitorService { private performanceObserver?: PerformanceObserver; startMonitoring(): void { if ('PerformanceObserver' in window) { this.performanceObserver = new PerformanceObserver((list) => { list.getEntries().forEach((entry) => { if (entry.entryType === 'navigation') { this.logNavigationTiming(entry as PerformanceNavigationTiming); } else if (entry.entryType === 'paint') { this.logPaintTiming(entry); } }); }); this.performanceObserver.observe({ entryTypes: ['navigation', 'paint', 'largest-contentful-paint'] }); } } private logNavigationTiming(entry: PerformanceNavigationTiming): void { console.log('导航性能指标:', { domContentLoaded: entry.domContentLoadedEventEnd - entry.domContentLoadedEventStart, loadComplete: entry.loadEventEnd - entry.loadEventStart, firstByte: entry.responseStart - entry.requestStart }); } private logPaintTiming(entry: PerformanceEntry): void { console.log(`${entry.name}: ${entry.startTime}ms`); } stopMonitoring(): void { if (this.performanceObserver) { this.performanceObserver.disconnect(); } } } // 3. Bundle分析和优化 // angular.json配置 { "build": { "builder": "@angular-devkit/build-angular:browser", "options": { "budgets": [ { "type": "initial", "maximumWarning": "2mb", "maximumError": "5mb" }, { "type": "anyComponentStyle", "maximumWarning": "6kb", "maximumError": "10kb" } ] } } }

Angular提供了完整的企业级开发解决方案,通过TypeScript、依赖注入和RxJS的强大组合,能够构建大型、可维护的前端应用。


📚 参考学习资料

📖 官方文档

🎓 优质教程

🛠️ 实践项目

🔧 开发工具

📝 深入阅读

💡 学习建议:建议从Angular CLI开始创建项目,学习组件和服务的基本概念,然后深入TypeScript和RxJS,最后掌握企业级开发模式。

Last updated on