Как разделить модели дерева состояний Mobx на несколько файлов?
У меня есть модель дерева состояний Mobx, которая выросла слишком долго, и я хотел бы разделить ее на несколько файлов javascript.
Вот демонстрация некоторого кода:
///file1.js
import { types } from "mobx-state-tree";
export const ExampleModel = types
.model("Example", {
id: types.identifier,
name: types.optional(types.string, ""),
anotherName: types.optional(types.string, ""),
})
.views(self => ({
get test() {
return "test"
}
}))
.views(self => ({
get anotherTest() {
return "anotherTest"
}
}))
.actions(self => ({
setName(name) {
self.name = name
}
}))
.actions(self => ({
setAnotherName(name) {
self.anotherName = name
}
}))
Я хочу разделить это на два файла, например:
///file1.js
import { types } from "mobx-state-tree";
export const ExampleModel = types
.model("Example", {
id: types.identifier,
name: types.optional(types.string, ""),
anotherName: types.optional(types.string, ""),
})
.views(self => ({
get test() {
return "test"
}
}))
.actions(self => ({
setName(name) {
self.name = name
}
}))
///file2.js
import { ExampleModel } from "./file1.js";
ExampleModel.views(self => ({
get anotherTest() {
return "anotherTest"
}
})).actions(self => ({
setAnotherName(name) {
self.anotherName = name
}
}))
Здесь вы можете видеть, что я пытаюсь переместить представление и действие в отдельный файл javascript. Я ожидаю, что мне нужно сделать какой-то импорт и экспорт между этими двумя файлами, но я не могу понять, как это сделать.
Я знаю, что Mobx State Tree имеет функции создания, как показано здесь: https://nathanbirrell.me/notes/composition-mobx-state-tree/
Но я предпочитаю что-то более простое, чем это... Я не хочу настраивать несколько моделей, мне просто нужна возможность распределить модель по нескольким файлам javascript.
2 ответа
Мы делаем это все время.
Просто экспортируйте свои действия и представления отдельно:
// file1.js
import { types } from "mobx-state-tree"
export const props = {
id: types.identifier,
name: types.optional(types.string, ""),
anotherName: types.optional(types.string, ""),
}
export const views = self => ({
get test() {
return "test"
}
})
export const actions = self => ({
setName(name) {
self.name = name
}
})
Затем создайте окончательный магазин из них:
// store.js
import { types } from "mobx-state-tree"
import * as file1 from "./file1"
import * as file2 from "./file2"
const Store = types
.model('Store')
.props(file1.props)
.views(file1.views)
.actions(file1.actions)
.props(file2.props)
.views(file2.views)
.actions(file2.actions)
export default Store
Вы также можете создавать свои собственные магазины для тестирования, только из одного файла:
// __tests__/file1.js
import { types } from "mobx-state-tree"
import { actions, views, props } from "./file1"
const Store = types
.model('Store')
.props(props)
.views(views)
.actions(actions)
const store = Store.create(myTestSnapshot)
test('setName should set the name prop', () => {
store.setName('john')
expect(store.name).toBe('john')
})
Выразительное, гибкое и простое составление моделей - одна из лучших функций в mobx-state-tree!:) Вот два примера, взятые прямо из соответствующего раздела в документации:
const Square = types
.model(
"Square",
{
width: types.number
}
)
.views(self => ({
surface() {
return self.width * self.width
}
}))
// create a new type, based on Square
const Box = Square
.named("Box")
.views(self => {
// save the base implementation of surface
const superSurface = self.surface
return {
// super contrived override example!
surface() {
return superSurface() * 1
},
volume() {
return self.surface * self.width
}
}
}))
// no inheritance, but, union types and code reuse
const Shape = types.union(Box, Square)
И еще один:
const CreationLogger = types.model().actions(self => ({
afterCreate() {
console.log("Instantiated " + getType(self).name)
}
}))
const BaseSquare = types
.model({
width: types.number
})
.views(self => ({
surface() {
return self.width * self.width
}
}))
export const LoggingSquare = types
.compose(
// combine a simple square model...
BaseSquare,
// ... with the logger type
CreationLogger
)
// ..and give it a nice name
.named("LoggingSquare")
Применяя это к вашим потребностям: Square
а также Box
может быть в разных файлах, где Box.js
импорт Square
от Square.js
в первом примере.
Точно такую же технику можно применить ко второму примеру.