【问题标题】:In mobX can a store "listen" to other another store, and execute a query whenever the other store changes?在 mobX 中,一个 store 可以“监听”另一个 store,并在另一个 store 发生变化时执行查询?
【发布时间】:2019-03-20 06:14:28
【问题描述】:

假设我有一个商店,其中有一个组织列表,用户可以“选择”组织,然后将其存储在“过滤器”数组中。

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[] 更改后重新运行)?

【问题讨论】:

    标签: javascript reactjs store mobx


    【解决方案1】:

    我想你可能正在寻找reactions

    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()
            );
        }
    
        // ...
    }
    

    如果您想要更多控制事件,另一种选择是使用observe

    const disposer = observe(this.organizationStore.filter, (change) => {
        // Change is an object with a couple properties that describe what has changed and how
    });
    

    但我认为反应对你来说很好。

    【讨论】:

    • 过滤器长度不会总是改变,实际上更常见的是整个过滤器数组被改变(并且大小保持相等)
    • @paul23 第一个函数是任何应该触发更新的函数。在这种情况下使用observer 可能会更好,这样您就可以应用额外的约束,例如新数组是否等于旧数组,或者所有元素是否相同等。如果您查看observe 文档,有一个包含有用信息的表格here
    猜你喜欢
    • 2017-12-02
    • 2015-08-02
    • 1970-01-01
    • 1970-01-01
    • 2017-08-21
    • 1970-01-01
    • 1970-01-01
    • 2020-02-24
    • 1970-01-01
    相关资源
    最近更新 更多