Angular 19:用信号和资源转换HTTP API调用
现代 Angular 开发随着每次版本的更新不断演进,带来了新的功能和开发范式,从而提升了开发者的体验和性能。Angular 19 引入了实验性的 resource()
API,并在之前引入的强大 Signal 架构基础上进行了扩展。在本文中,我们将探讨如何从传统的 HttpClient
基础的 API 调用过渡到使用 Angular 最新特性的 Signals 和新资源。
传统的有关这些方法的分步指南,包括实用示例和小贴士,请看我在 YouTube 上的视频:
HttpClient
和 RxJS 使用方式
大多数 Angular 开发人员都熟悉使用 HttpClient
服务和 RxJS Observable
处理 HTTP API 请求的传统方法。如下是一个获取 Todo
项列表的示例:
TodoService
):
import { HttpClient } from '@angular/common/http';
import { inject, Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Todo } from './todo.model';
@Injectable()
export class TodoService {
private readonly http: HttpClient = inject(HttpClient);
public getTodos(): Observable<Todo[]> {
return this.http.get<Todo[]>('https://jsonplaceholder.typicode.com/todos?_limit=10');
}
}
组件:
导入 { 组件 } from '@angular/core';
导入 { 待办事项服务 } from './待办事项服务';
导入 { 可观察 } from 'rxjs';
@组件({
选择器: 'app-root',
模板URL: './app.component.html',
样式URL: ['./app.component.scss'],
})
导出 类 AppComponent {
公共 待办事项$: 可观察<待办事项[]> = this.待办事项服务.getTodos();
构造器(私有 readonly 待办事项服务: 待办事项服务) {}
}
HTML:
@for (todo of (todos$ | async)); track todo.id {
<div>
<span>{{ todo.title }}</span>
</div>
}
转向使用信号和异步管道
使用 Angular Signals,你可以更简洁地管理反应式状态,无需手动订阅。下面是如何将组件改为使用 Signals:
一个重构后的组件: import { AsyncPipe } from '@angular/common';
import { Component, computed, inject, toSignal } from '@angular/core';
import { Todo } from './todo模型';
import { TodoService } from './todo服务';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
imports: [AsyncPipe],
providers: [TodoService],
})
export class AppComponent {
private readonly todoService = inject(TodoService);
public todos = toSignal(this.todoService.getTodos(), { initialValue: [] });
}
最新的HTML
@for (todo of todos(); track todo.id) {
<div>
<span>{{ todo.title }}</span>
</div>
}
在上述代码中,@for
循环遍历 todos
列表,并追踪每个 todo
的 id
。对于每个 todo
,生成一个包含 todo.title
的 div
。
这去掉了 | async
的必要性,并通过利用 Signals 来实现反应式更新,从而简化状态的管理。
resource()
API
resource()
API 提供了一种处理异步数据获取的新方法,内置了缓存和刷新的能力。我们用它来获取 Todo
项吧。
resource()
更新组件:
import { AsyncPipe } from '@angular/common';
import { Component, computed, inject, resource, Signal } from '@angular/core';
import { Todo } from './todo.model';
import { TodoService } from './todo.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
imports: [AsyncPipe],
providers: [TodoService],
})
export class AppComponent {
private readonly todoService = inject(TodoService);
public todoResource = resource({
loader: () => {
return fetch(
'https://jsonplaceholder.typicode.com/todos?_limit=10'
).then((response) => response.json() as Promise<Todo[]>);
},
});
public calculatedTodos = computed(() => this.todoResource.value() || []);
// 计算任务列表
}
更新的HTML:
对于todos中的每个待办事项(跟踪其id),生成一个包含其标题的div元素。
在这里,resource()
API 简化了异步加载的逻辑,同时,自动管理缓存和响应式。
- 传统的
HttpClient
和| async
方法仍然强大,但可能会显得繁琐。 - 信号提供了一种更声明式的管理方式来处理反应式数据,避免了手动订阅的麻烦。
- 虽然仍处于实验阶段,
resource()
API 提供了一个内置缓存的异步数据获取的前景可期的替代方案。
干了!
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦