在 emberjs 中从组件 类 调用 API 调用是一种好方法吗?
Is it a good way to call API calls from component classes in emberjs?
我现在正在学习 emberjs,我想知道这是否是在组件 classes 的函数内发出获取请求(例如按钮点击)并将数据存储在 class 组件。例如:
export default class ExampleComponent extends Component {
@tracked items;
@action async toggleCall() {
await fetch(...)
.then(...)
}
}
或者您在 emberjs 中以不同的方式执行此操作?
是的,这是一个非常合理的方法。
但是,你需要以某种方式手动调用toggleCall
。
我最喜欢在组件中加载东西或做任何事情异步的方式是使用“资源”通过派生数据懒惰地和反应性地这样做。
有一个名为 trackedFunction
的实用程序来自:https://github.com/nullvoxpopuli/ember-resources
Specific docs here
您的示例可以重写为:
import Component from '@glimmer/component';
import { trackedFunction } from 'ember-resources';
export default class Example extends Component {
fetchItems = trackedFunction(this, async () => {
let response = await fetch( /* ... */);
return await response.json();
});
get items() {
// specify a default value of empty array when value is undefined
// (value is undefined before the function finishes running)
return this.fetchItems.value ?? [];
}
}
主要区别:
trackedFunction
将在访问时自动调用
- repeat-accesses 不会重新调用函数
- 在
trackedFunction
中的 await
之前使用的任何 @tracked
数据将“纠缠”,因此对该 @tracked
数据的更改将导致函数 运行 再次,例如,如果你有一个查询参数
@tracked filter = 'name:starts_with=a';
fetchItems = trackedFunction(this, async () => {
let url = `...?${this.filter}`;
let response = await fetch(url /* ... */);
return await response.json();
});
fetchItems
是反应式的,因为现在当 filter
改变时,fetchItems
会重新调用自己。
但是,如果您打算保留点击请求行为(这很常见!),您可能会对 ember-concurrency 感兴趣,它提供了一些很好的人体工程学实用程序来处理/保护您的来自使用人机交互的愚蠢行为的数据——例如在用户单击按钮后不重新请求,并在请求完成之前再次单击该按钮。
您的示例将是:
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { dropTask } from 'ember-concurrency';
export default class Example extends Component {
@dropTask
*fetchItems() {
let response = await fetch( /* ... */);
return await response.json();
}
get items() {
return this.fetchItems.lastSuccessful.value ?? [];
}
// click handler can be called any number of times,
// which would, in turn, call fetchItems any number of times,
// but only one `fetch` request will ever run at a given time.
@action
handleClick() {
this.fetchItems.perform();
}
}
关于 ember-并发的文档:https://ember-concurrency.com/
我现在正在学习 emberjs,我想知道这是否是在组件 classes 的函数内发出获取请求(例如按钮点击)并将数据存储在 class 组件。例如:
export default class ExampleComponent extends Component {
@tracked items;
@action async toggleCall() {
await fetch(...)
.then(...)
}
}
或者您在 emberjs 中以不同的方式执行此操作?
是的,这是一个非常合理的方法。
但是,你需要以某种方式手动调用toggleCall
。
我最喜欢在组件中加载东西或做任何事情异步的方式是使用“资源”通过派生数据懒惰地和反应性地这样做。
有一个名为 trackedFunction
的实用程序来自:https://github.com/nullvoxpopuli/ember-resources
Specific docs here
您的示例可以重写为:
import Component from '@glimmer/component';
import { trackedFunction } from 'ember-resources';
export default class Example extends Component {
fetchItems = trackedFunction(this, async () => {
let response = await fetch( /* ... */);
return await response.json();
});
get items() {
// specify a default value of empty array when value is undefined
// (value is undefined before the function finishes running)
return this.fetchItems.value ?? [];
}
}
主要区别:
trackedFunction
将在访问时自动调用- repeat-accesses 不会重新调用函数
- 在
trackedFunction
中的await
之前使用的任何@tracked
数据将“纠缠”,因此对该@tracked
数据的更改将导致函数 运行 再次,例如,如果你有一个查询参数
@tracked filter = 'name:starts_with=a';
fetchItems = trackedFunction(this, async () => {
let url = `...?${this.filter}`;
let response = await fetch(url /* ... */);
return await response.json();
});
fetchItems
是反应式的,因为现在当 filter
改变时,fetchItems
会重新调用自己。
但是,如果您打算保留点击请求行为(这很常见!),您可能会对 ember-concurrency 感兴趣,它提供了一些很好的人体工程学实用程序来处理/保护您的来自使用人机交互的愚蠢行为的数据——例如在用户单击按钮后不重新请求,并在请求完成之前再次单击该按钮。
您的示例将是:
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { dropTask } from 'ember-concurrency';
export default class Example extends Component {
@dropTask
*fetchItems() {
let response = await fetch( /* ... */);
return await response.json();
}
get items() {
return this.fetchItems.lastSuccessful.value ?? [];
}
// click handler can be called any number of times,
// which would, in turn, call fetchItems any number of times,
// but only one `fetch` request will ever run at a given time.
@action
handleClick() {
this.fetchItems.perform();
}
}
关于 ember-并发的文档:https://ember-concurrency.com/