如果您想阻止查询自动运行,可以使用 enabled = false 选项。enabled 选项也接受一个返回布尔值的回调函数。
当 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>
// 🚀 applying the filter will enable and execute the query
<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>
// 🚀 applying the filter will enable and execute the query
<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>
// 🚀 applying the filter will enable and execute the query
<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>
// 🚀 applying the filter will enable and execute the query
<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,
}))
}