我创建了两个Mobx State Tree状态:Ui和Data。
UI.ts:
export const UI = t
.model('UI', {
widthPage: t.optional(t.number, 0),
heightPage: t.optional(t.number, 0),
})
.views(self => ({
get activeCategory() {
// here I need to do some operation on values attribute of Data store
},
}))
.actions(self => ({
}))
和Data.ts:
import { types as t } from 'mobx-state-tree'
import {
ValueType,
} from '../lib/types'
const values = require('../dataset/normalized/values.csv')
export const Data = t
.model('Data', {
values: t.optional(t.frozen<ValueType[]>(), values),
})
.views(self => ({
getSomething(country: string): number {
return 5
},
}))
.actions(self => ({
}))
然后我还有文件index.ts和main.tsx。
index.ts:
export const State = t
.model('State', {
ui: t.optional(UI, {}),
data: t.optional(Data, {}),
})
.views(self => ({}))
.actions(self => ({
resetSubState(subState: typeof self.ui | typeof self.data) {
const subStateName = subState.$treenode.subpath
self[subStateName] = {}
},
}))
export type StateType = typeof State.Type
export interface IStateable {
state?: StateType
}
main.tsx:
const state = State.create({})
如何从UI状态使用Data状态的操作,反之亦然?我看到了方法getEnv
但我不知道如何使用它...
最简单的方法是让activeCategory
的调用者将数据从Data
传递到视图中。
这意味着不使用计算属性:
getActiveCategory(dataStore.whateverPropIsNeeded, ...)
如果这些商店不属于同一个树,那么getEnv对于一个方法来说也不会太糟糕(在你的例子中它们是同一棵树的一部分)。
const DataStore = Data.create({});
const UIStore = UI.create({}, { dataStore });
然后在UIStore你可以做到,
const dataStore = getEnv(self).dataStore;
如果它们是同一个树的一部分,则getEnv不是一个很好的方法,因为MST有一个约束,即树中的所有节点必须具有相同的依赖关系(getEnv返回相同的对象)。
或者,Data可以是UI的子级。对于大多数用例,我并不喜欢这种方法。
最后一个解决方案......这两个商店的父级可以公开同时使用UI和数据的视图。可能会导致一个臃肿的模型..这些解决方案都不是完美的所以我很想看到其他答案弹出。
getEnv()
是一种从MST中的任何节点访问一些环境变量(您之前传递给根节点)的方法,无论深度如何(想想React中的Context)。
在创建新状态树时,可以通过将对象作为第二个参数传递给
.create
调用来传递特定于环境的数据。该对象应该(浅)不可变,并且可以通过调用getEnv(self)
由树中的任何模型访问。这对于注入环境或特定于测试的实用程序(如传输层,记录器等)非常有用。
非常方便,但似乎不是你需要的。
有许多不同的方法可以遍历MST。例如,您可以将unique identifier分配给任何节点,然后可以从MST中的任何其他节点检索它。
您还可以使用getRoot(self),getParent(self, depth=1)或getParentOfType(self, type)帮助程序从给定节点遍历树。
但在你的情况下最简单的方法是使用resolvePath(node, path)。所以基本上从data
中的任何视图或动作中你可以做到:
import { types as t, resolvePath } from 'mobx-state-tree'
// ...
resolvePath(self, '../ui').activeCategory