Как разделить модели дерева состояний Mobx на несколько файлов? - PullRequest
0 голосов
/ 07 января 2019

У меня есть модель дерева состояний 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 ]

0 голосов
/ 08 января 2019

Выразительное, гибкое и простое составление модели - одна из лучших функций в 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 в первом примере.

Точно такую ​​же технику можно применить ко второму примеру.

0 голосов
/ 07 января 2019

Мы делаем это постоянно.

Просто экспортируйте свои действия и представления отдельно:

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