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 开发提升到新的水平!