在 mobX 中,一个商店 "listen" 可以到另一个商店,并在另一个商店发生变化时执行查询吗?
In mobX can a store "listen" to other another store, and execute a query whenever the other store changes?
假设我有一个商店,里面有一个组织列表,用户可以 "select" 个组织,然后存储在 "filter" 数组中。
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[]
更改后重新运行)?
我认为您可能正在寻找 reactions。
Reaction - A variation on autorun that gives more fine grained control on which observables will be tracked. It takes two functions, the first one (the data function) is tracked and returns data that is used as input for the second one, the effect function.
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()
);
}
// ...
}
另一个选项,如果你想要事件更多的控制,是使用 observe
const disposer = observe(this.organizationStore.filter, (change) => {
// Change is an object with a couple properties that describe what has changed and how
});
不过我觉得你反应还可以。
假设我有一个商店,里面有一个组织列表,用户可以 "select" 个组织,然后存储在 "filter" 数组中。
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[]
更改后重新运行)?
我认为您可能正在寻找 reactions。
Reaction - A variation on autorun that gives more fine grained control on which observables will be tracked. It takes two functions, the first one (the data function) is tracked and returns data that is used as input for the second one, the effect function.
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()
);
}
// ...
}
另一个选项,如果你想要事件更多的控制,是使用 observe
const disposer = observe(this.organizationStore.filter, (change) => {
// Change is an object with a couple properties that describe what has changed and how
});
不过我觉得你反应还可以。