angular-best-practices

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Angular Best Practices

Angular最佳实践

Curated rules for building performant, maintainable Angular applications. Library-specific rules (NgRx, SignalStore, TanStack Query) available as optional skills.
为构建高性能、可维护的Angular应用整理的规则。还提供了针对特定库(NgRx、SignalStore、TanStack Query)的可选规则。

When to Use

适用场景

Apply these practices when:
  • Creating components, services, and directives
  • Setting up state management with Signals
  • Writing unit, component, and E2E tests
  • Optimizing bundle size and runtime performance
  • Implementing forms, routing, and SSR
在以下场景中应用这些实践:
  • 创建组件、服务和指令
  • 使用Signals设置状态管理
  • 编写单元测试、组件测试和E2E测试
  • 优化包体积和运行时性能
  • 实现表单、路由和SSR

Categories

分类

CategoryRulesImpact
Bundle Optimization5CRITICAL
Signals & Reactivity5HIGH
Change Detection5HIGH
Component Patterns4HIGH
RxJS Patterns5HIGH
Testing6HIGH
TypeScript14MEDIUM
分类规则数量影响等级
包体积优化5关键(CRITICAL)
Signals与响应式编程5高(HIGH)
变更检测5高(HIGH)
组件模式4高(HIGH)
RxJS模式5高(HIGH)
测试6高(HIGH)
TypeScript14中(MEDIUM)

Optional Library Skills

可选库规则

Install library-specific rules alongside this core skill:
LibraryInstall Command
NgRx
npx skills add alfredoperez/angular-best-practices/skills/angular-best-practices-ngrx
SignalStore
npx skills add alfredoperez/angular-best-practices/skills/angular-best-practices-signalstore
TanStack Query
npx skills add alfredoperez/angular-best-practices/skills/angular-best-practices-tanstack
除核心规则外,可安装针对特定库的规则:
安装命令
NgRx
npx skills add alfredoperez/angular-best-practices/skills/angular-best-practices-ngrx
SignalStore
npx skills add alfredoperez/angular-best-practices/skills/angular-best-practices-signalstore
TanStack Query
npx skills add alfredoperez/angular-best-practices/skills/angular-best-practices-tanstack

Quick Reference

快速参考

Modern Angular Patterns

现代Angular模式

PatternUseAvoid
Signal inputs
input<T>()
@Input()
Signal outputs
output<T>()
@Output()
Dependency injection
inject()
Constructor injection
Control flow
@if
,
@for
,
@switch
*ngIf
,
*ngFor
Class binding
[class.active]
[ngClass]
Change detection
OnPush
Default
Derived state
computed()
Getters
模式推荐用法避免用法
Signal输入
input<T>()
@Input()
Signal输出
output<T>()
@Output()
依赖注入
inject()
构造函数注入
控制流
@if
,
@for
,
@switch
*ngIf
,
*ngFor
类绑定
[class.active]
[ngClass]
变更检测
OnPush
默认模式
派生状态
computed()
Getters

Component Template

组件模板

typescript
@Component({
  selector: 'app-user-card',
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    @if (user(); as u) {
      <h2>{{ u.name }}</h2>
      <button (click)="selected.emit(u)">Select</button>
    }
  `,
})
export class UserCardComponent {
  user = input.required<User>();
  selected = output<User>();
}
typescript
@Component({
  selector: 'app-user-card',
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    @if (user(); as u) {
      <h2>{{ u.name }}</h2>
      <button (click)="selected.emit(u)">Select</button>
    }
  `,
})
export class UserCardComponent {
  user = input.required<User>();
  selected = output<User>();
}

Service Template

服务模板

typescript
@Injectable({ providedIn: 'root' })
export class UserService {
  private http = inject(HttpClient);

  getUsers(): Observable<User[]> {
    return this.http.get<User[]>('/api/users');
  }
}
typescript
@Injectable({ providedIn: 'root' })
export class UserService {
  private http = inject(HttpClient);

  getUsers(): Observable<User[]> {
    return this.http.get<User[]>('/api/users');
  }
}

State with Signals

使用Signals管理状态

typescript
export class CounterComponent {
  count = signal(0);
  doubled = computed(() => this.count() * 2);

  increment() {
    this.count.update(c => c + 1);
  }
}
typescript
export class CounterComponent {
  count = signal(0);
  doubled = computed(() => this.count() * 2);

  increment() {
    this.count.update(c => c + 1);
  }
}

License

许可证

MIT
MIT