В mobX может ли магазин «слушать» другой другой магазин и выполнять запрос всякий раз, когда другой магазин изменяется? - PullRequest
0 голосов
/ 15 октября 2018

Скажем, у меня есть магазин, в котором есть список организаций, пользователь может "выбирать" организации, которые затем сохраняются в массиве "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[] изменений)?

1 Ответ

0 голосов
/ 15 октября 2018

Я думаю, что вы, вероятно, ищете реакции .

Реакция - вариант автозапуска, который дает более точный контроль над тем, какие наблюдаемые будут отслеживаться.Он принимает две функции, первая (функция данных) отслеживается и возвращает данные, которые используются в качестве входных данных для второй, функции эффекта.

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
});

Но я думаю, что реакция вам подходит.

...