Angular 中的函数式编程:探索注入和资源
Angular 不断发展的生态系统正在转向更具**功能性和响应性的编程**范式。借助**信号**、**资源 API**和**注入函数**等工具,开发人员可以简化应用程序逻辑、减少样板代码并增强可重用性。
这篇博文探讨了 Angular 的现代功能如何帮助开发人员以干净、声明性和反应性的方式处理异步逻辑。
Angular 函数式特性的主要优点
步骤 1:API 和数据模型
在此示例中,我们将从 REST API 获取帖子。每篇帖子均具有以下结构:
export interface Post { userId: number; id: number; title: "string;" body: string; }
API 的基本 URL 通过 `InjectionToken` 提供:
import { InjectionToken } from '@angular/core'; export const API_BASE_URL = new InjectionToken('API_BASE_URL', { providedIn: 'root', factory: () => 'https://jsonplaceholder.typicode.com', });
第 2 步:定义数据获取函数
1. 传统的基于 RxJS 的方法
以下函数使用 Angular 的 `HttpClient` 通过其 ID 获取帖子:
import { HttpClient } from '@angular/common/http'; import { inject } from '@angular/core'; import { Observable } from 'rxjs'; import { API_BASE_URL } from '../tokens/base-url.token'; import { Post } from './post.model'; export function getPostById(postId: number): Observable{ const http = inject(HttpClient); const baseUrl = inject(API_BASE_URL); return http.get (`${baseUrl}/posts/${postId}`); }
要在组件中使用此功能,您可以将其绑定到可观察对象并使用“异步”管道显示结果:
import { AsyncPipe, JsonPipe } from '@angular/common'; import { Component, signal } from '@angular/core'; import { getPostById } from './shared/posts.inject'; @Component({ selector: 'app-root', standalone: true, imports: [AsyncPipe, JsonPipe], template: ` @if (post$ | async; as post) {{{ post | json }}
} @else {Loading...
} `, }) export class AppComponent { private readonly postId = signal(1); protected readonly post$ = getPostById(this.postId()); }
限制
2.基于信号的资源API方法
Resource API 简化了响应性和状态管理。以下是使用 Resource API 的函数:
import { inject, resource, ResourceRef, Signal } from '@angular/core'; import { API_BASE_URL } from '../tokens/base-url.token'; export function getPostByIdResource(postId: Signal): ResourceRef { const baseUrl = inject(API_BASE_URL); return resource ({ request: () => ({ id: postId() }), loader: async ({ request, abortSignal }) => { const response = await fetch(`${baseUrl}/posts/${request.id}`, { signal: abortSignal, }); return response.json(); }, }); }
这种方法:
在组件中:
import { JsonPipe } from '@angular/common'; import { Component, signal } from '@angular/core'; import { getPostByIdResource } from './shared/posts.inject'; @Component({ selector: 'app-root', standalone: true, imports: [JsonPipe], template: ` @if (post.isLoading()) {Loading...
} @else if (post.error()) {Error: {{ post.error() }}
} @else {{{ post.value() | json }}
} `, }) export class AppComponent { private readonly postId = signal(1); protected readonly post = getPostByIdResource(this.postId); }
资源 API 的主要功能
声明式状态管理
Resource API 会自动管理“正在加载”、“错误”和“成功”等状态。这样就无需自定义标志,并确保模板更清晰。
反应性
Resource API 与 Signals 紧密集成。对 Signal 的更改会自动触发加载器函数,确保您的 UI 始终反映最新数据。
错误处理
错误集中并通过`.error()`公开,简化了模板中的错误管理。
自动生命周期管理
当依赖项(例如 `postId`)发生变化时,API 会取消正在进行的请求,从而防止竞争条件和陈旧数据。
RxJS 与 Resource API:快速比较
结论
Angular 的“inject”函数和基于信号的资源 API 代表了简化异步逻辑的一次飞跃。借助这些工具,开发人员可以:
Resource API 尤其适合现代 Angular 项目,可提供自动响应和声明式状态处理。立即开始探索这些功能,将您的 Angular 开发提升到新的水平!