查询是一个声明式的、与唯一键绑定的异步数据源依赖。查询可以与任何基于 Promise 的方法(包括 GET 和 POST 方法)一起使用,从服务器获取数据。如果你的方法会修改服务器上的数据,我们建议使用Mutations。
要在组件或服务中订阅查询,请调用 injectQuery,并至少提供
import { injectQuery } from '@tanstack/angular-query-experimental'
export class TodosComponent {
info = injectQuery(() => ({ queryKey: ['todos'], queryFn: fetchTodoList }))
}
import { injectQuery } from '@tanstack/angular-query-experimental'
export class TodosComponent {
info = injectQuery(() => ({ queryKey: ['todos'], queryFn: fetchTodoList }))
}
您提供的**唯一键**在内部用于在整个应用程序中重新获取、缓存和共享您的查询。
injectQuery 返回的查询结果包含了你在模板和其他任何数据使用中需要的所有查询信息。
result = injectQuery(() => ({ queryKey: ['todos'], queryFn: fetchTodoList }))
result = injectQuery(() => ({ queryKey: ['todos'], queryFn: fetchTodoList }))
result 对象包含了一些你为了提高效率而需要了解的非常重要的状态。查询在任何给定时刻只能处于以下状态之一:
除了这些主要状态之外,根据查询的状态,还可以获得更多信息:
对于大多数查询,通常足以检查 isPending 状态,然后是 isError 状态,最后假设数据可用并渲染成功状态。
@Component({
selector: 'todos',
standalone: true,
template: `
@if (todos.isPending()) {
<span>Loading...</span>
} @else if (todos.isError()) {
<span>Error: {{ todos.error()?.message }}</span>
} @else {
<!-- We can assume by this point that status === 'success' -->
@for (todo of todos.data(); track todo.id) {
<li>{{ todo.title }}</li>
} @empty {
<li>No todos found</li>
}
}
`,
})
export class PostsComponent {
todos = injectQuery(() => ({
queryKey: ['todos'],
queryFn: fetchTodoList,
}))
}
@Component({
selector: 'todos',
standalone: true,
template: `
@if (todos.isPending()) {
<span>Loading...</span>
} @else if (todos.isError()) {
<span>Error: {{ todos.error()?.message }}</span>
} @else {
<!-- We can assume by this point that status === 'success' -->
@for (todo of todos.data(); track todo.id) {
<li>{{ todo.title }}</li>
} @empty {
<li>No todos found</li>
}
}
`,
})
export class PostsComponent {
todos = injectQuery(() => ({
queryKey: ['todos'],
queryFn: fetchTodoList,
}))
}
如果您不喜欢布尔值,也可以随时使用 status 状态。
@Component({
selector: 'todos',
standalone: true,
template: `
@switch (todos.status()) {
@case ('pending') {
<span>Loading...</span>
}
@case ('error') {
<span>Error: {{ todos.error()?.message }}</span>
}
<!-- also status === 'success', but "else" logic works, too -->
@default {
<ul>
@for (todo of todos.data(); track todo.id) {
<li>{{ todo.title }}</li>
} @empty {
<li>No todos found</li>
}
</ul>
}
}
`,
})
class TodosComponent {}
@Component({
selector: 'todos',
standalone: true,
template: `
@switch (todos.status()) {
@case ('pending') {
<span>Loading...</span>
}
@case ('error') {
<span>Error: {{ todos.error()?.message }}</span>
}
<!-- also status === 'success', but "else" logic works, too -->
@default {
<ul>
@for (todo of todos.data(); track todo.id) {
<li>{{ todo.title }}</li>
} @empty {
<li>No todos found</li>
}
</ul>
}
}
`,
})
class TodosComponent {}
如果你在访问 data 之前已经检查了 pending 和 error,TypeScript 也会正确地缩小 data 的类型。
除了 status 字段外,你还将获得一个额外的 fetchStatus 属性,具有以下选项:
后台重新获取和 stale-while-revalidate 逻辑使得 status 和 fetchStatus 的所有组合都可能出现。例如:
因此,请记住,查询可能处于 pending 状态,但实际上并没有获取数据。根据经验法则: