javascript - 在 mobX 中,一个 store 可以“监听”另一个 store,并在另一个 store 发生变化时执行查询?
问题描述
假设我有一个商店,其中有一个组织列表,用户可以“选择”组织,然后将其存储在“过滤器”数组中。
export class OrganizationStore extends ArrayStore {
//organizations = new Map();
constructor( ...args) {
super(args);
this.organizations = new Map();
this.filter = [];
this.getter_url = '/organization/get-organizations';
}
async getData() {
const full_url = new URL(this.getter_url);
const options = {};
options.method = 'GET';
options.credentials = process.env.NODE_ENV === 'production' ? 'same-origin' : 'include';
const response = await fetch(full_url, options);
if (response.ok) {
const d = await response.json();
this.buildStore(d);
}
}
buildStore(values) {
this.organizations.clear();
for (const {id, name} of values) {
this.organizations.set(id, new Organization(id, name));
}
}
get count() {
return this.organizations.size;
}
}
decorate(OrganizationStore, {
organizations: observable,
filter: observable,
count: computed,
});
export class Organization {
constructor(id, name) {
this.id = id;
this.name = name;
}
}
另一家商店也存在
export class UserStore extends ArrayStore {
constructor(organizationStore, ...args) {
super(args);
this.users = [];
this.getter_url = '/users/get-users';
this.organizationStore = organizationStore;
}
async getData() {
const full_url = new URL(this.getter_url);
const options = {};
options.method = 'GET';
options.credentials = process.env.NODE_ENV === 'production' ? 'same-origin' : 'include';
query = {filter: this.organizationStore.filter()};
//how to make this line "observe" the original store
Object.keys(query).forEach(key => full_url.searchParams.append(key, options.query[key]));
const response = await fetch(full_url, options);
if (response.ok) {
const d = await response.json();
this.buildStore(d);
}
}
}
现在(如何)我可以让商店自动刷新(让 getData 在更改后重新运行organizationStore.filter[]
)?
解决方案
我想你可能正在寻找反应。
Reaction - 自动运行的一种变体,可以更细粒度地控制要跟踪的可观察对象。它需要两个函数,第一个(数据函数)被跟踪并返回用作第二个函数(效果函数)的输入的数据。
export class UserStore extends ArrayStore {
constructor(organizationStore, ...args) {
super(args);
this.users = [];
this.getter_url = '/users/get-users';
this.organizationStore = organizationStore;
// Dispose of this when done with it
const disposer = reaction(
() => this.organizationStore.filter.length,
() => this.getData()
);
}
// ...
}
如果您想要更多控制事件,另一种选择是使用观察
const disposer = observe(this.organizationStore.filter, (change) => {
// Change is an object with a couple properties that describe what has changed and how
});
但我认为反应对你来说很好。