如果你希望阻止某个查询自动执行,可以使用 enabled = false 选项。该选项也支持传入返回布尔值的回调函数。
当 enabled 为 false 时:
TypeScript 用户可考虑使用 skipToken 作为 enabled = false 的替代方案
@Component({
selector: 'todos',
template: `<div>
<button (click)="query.refetch()">Fetch Todos</button>
@if (query.data()) {
<ul>
@for (todo of query.data(); track todo.id) {
<li>{{ todo.title }}</li>
}
</ul>
} @else {
@if (query.isError()) {
<span>Error: {{ query.error().message }}</span>
} @else if (query.isLoading()) {
<span>Loading...</span>
} @else if (!query.isLoading() && !query.isError()) {
<span>Not ready ...</span>
}
}
<div>{{ query.isLoading() ? 'Fetching...' : '' }}</div>
</div>`,
})
export class TodosComponent {
query = injectQuery(() => ({
queryKey: ['todos'],
queryFn: fetchTodoList,
enabled: false,
}))
}
@Component({
selector: 'todos',
template: `<div>
<button (click)="query.refetch()">Fetch Todos</button>
@if (query.data()) {
<ul>
@for (todo of query.data(); track todo.id) {
<li>{{ todo.title }}</li>
}
</ul>
} @else {
@if (query.isError()) {
<span>Error: {{ query.error().message }}</span>
} @else if (query.isLoading()) {
<span>Loading...</span>
} @else if (!query.isLoading() && !query.isError()) {
<span>Not ready ...</span>
}
}
<div>{{ query.isLoading() ? 'Fetching...' : '' }}</div>
</div>`,
})
export class TodosComponent {
query = injectQuery(() => ({
queryKey: ['todos'],
queryFn: fetchTodoList,
enabled: false,
}))
}
永久禁用查询会使你无法使用 TanStack Query 的许多优秀特性(如后台重新获取),这也不符合惯用模式。这会让你从声明式模式(定义查询运行依赖条件)退回到命令式模式(点击按钮时才获取数据),且无法向 refetch 传递参数。通常你需要的只是一个延迟初始获取的惰性查询:
enabled 选项不仅能永久禁用查询,还能实现动态启用/禁用。典型场景是筛选表单——只有当用户输入筛选值后才发起首次请求:
@Component({
selector: 'todos',
template: `
<div>
// 🚀 应用筛选条件时将启用并执行查询
<filters-form onApply="filter.set" />
<todos-table data="query.data()" />
</div>
`,
})
export class TodosComponent {
filter = signal('')
todosQuery = injectQuery(() => ({
queryKey: ['todos', this.filter()],
queryFn: () => fetchTodos(this.filter()),
enabled: !!this.filter(),
}))
}
@Component({
selector: 'todos',
template: `
<div>
// 🚀 应用筛选条件时将启用并执行查询
<filters-form onApply="filter.set" />
<todos-table data="query.data()" />
</div>
`,
})
export class TodosComponent {
filter = signal('')
todosQuery = injectQuery(() => ({
queryKey: ['todos', this.filter()],
queryFn: () => fetchTodos(this.filter()),
enabled: !!this.filter(),
}))
}
惰性查询会始终处于 status: 'pending' 状态,因为 pending 表示尚无数据。虽然技术上是正确的,但由于当前并未获取数据(查询未被 启用),这个状态可能不适合用来显示加载指示器。
对于禁用或惰性查询,可以使用 isLoading 标志。这是一个衍生标志,由以下条件计算得出:
isPending && isFetching
因此只有当查询首次获取数据时才会返回 true。
TypeScript 用户可以使用 skipToken 禁用查询。适用于需要根据条件禁用查询,同时保持类型安全的场景。
重要提示:injectQuery 返回的 refetch 无法与 skipToken 配合使用。除此之外,skipToken 的行为与 enabled: false 完全一致。
import { skipToken, injectQuery } from '@tanstack/query-angular'
@Component({
selector: 'todos',
template: `
<div>
// 🚀 应用筛选条件时将启用并执行查询
<filters-form onApply="filter.set" />
<todos-table data="query.data()" />
</div>
`,
})
export class TodosComponent {
filter = signal('')
todosQuery = injectQuery(() => ({
queryKey: ['todos', this.filter()],
queryFn: this.filter() ? () => fetchTodos(this.filter()) : skipToken,
}))
}
import { skipToken, injectQuery } from '@tanstack/query-angular'
@Component({
selector: 'todos',
template: `
<div>
// 🚀 应用筛选条件时将启用并执行查询
<filters-form onApply="filter.set" />
<todos-table data="query.data()" />
</div>
`,
})
export class TodosComponent {
filter = signal('')
todosQuery = injectQuery(() => ({
queryKey: ['todos', this.filter()],
queryFn: this.filter() ? () => fetchTodos(this.filter()) : skipToken,
}))
}