2

我正在尝试让 Mobx 的自动运行正常工作。

我的用例是我有一个模型,我喜欢在它更改时对其进行序列化(或脱水)并将该信息添加到另一个模型的数据中。这给我带来了模型状态的基本时间旅行。两者都是可观察的。

编辑:模型分离的想法是一个是应用程序的数据模型,另一个应该是完全独立的库,我可以从应用程序中使用。我需要定期跟踪应用程序中的更改,但在同一页面上显示状态工具的 UI。

现在,自动运行似乎对我实际跟踪的内容做出了自己的推断。当我在观察模型的实例化中移动模型实例时,发生更改时不再调用自动运行。在模块顶层创建模型实例时,它按我的预期工作。这是我只更改了观察模型的一个属性(每次自动运行调用都会更改的属性)的时候。当我尝试在观察模型中一次更改两件事时,现在也为这些更改调用了自动运行,从而导致了一个无休止的循环(Mobx 捕捉到了这一点)。

我想知道如何更明确地表达我正在使用自动运行功能跟踪的内容,或者是否有其他方法可以跟踪模型更改并在发生任何事情时更新其他模型。


使用代码示例进行编辑。

这就是我所做的(大大简化了):

class DataModel {
    @observable one_state = null;
}

class StateStore {
    @observable states = [];
}

let data = new DataModel();
let store = new StateStore();

autorun(() => {
   store.states.push(data.one_state);
   console.log("new data", toJSON(store.states));
});

data.one_state = "change 1";
data.one_state = "change 2";

这会产生循环依赖,因为原始数据模型更改和结果存储更改都会调用 autorun 而我只对跟踪对前者的更改感兴趣。


编辑工作结果:

class DataModel {
    @observable one_state = null;
}

class StateStore {
    @observable states = asFlat([]);
}

let data = new DataModel();
let store = new StateStore();

autorun(() => {
   store.states.push(data.one_state);
});

data.one_state = "change 1";
data.one_state = "change 2";

根据@mweststrate 的回答,将 asFlat 与 store 的 states 变量一起使用并从 autorun 中删除日志记录打破了问题循环。

4

1 回答 1

7

没有任何真正的代码来回答这个问题有点困难。你能分享一些代码吗?但是请注意,如果您稍微改变一下思路,MobX 效果最好:与其命令式地说“如果 X 发生,则应该更改 Y”,不如说“Y 可以从 X 派生”。如果你按照这些思路思考,MobX 将真正开始大放异彩。

因此,与其拥有两个可观察的模型,我认为其中一个应该是另一个的推导(通过确实使用计算)。那有意义吗?否则,请随时详细说明您的问题:)

编辑:

好的,谢谢你的代码。您应该删除日志语句以避免它循环;当前您记录状态模型,因此每次更改时,自动运行都会运行,添加第一项(再次!),更改 stateModel 等...

其次,我不确定状态列表是否应该是可观察的,但至少它的内容不应该是可观察的(因为它是一个快照并且每个状态的数据不应该改变)。为了表达这一点,您可以使用asFlat修饰符,它表明 states 集合应该只是浅可观察的:@observable states = asFlat([]).

这是否回答你的问题?

于 2016-04-29T09:50:59.327 回答