Как использовать действия из разных состояний в дереве состояний mobx - PullRequest
0 голосов
/ 12 февраля 2019

Я создал два состояния 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({})

Как использовать действияданных состояния из пользовательского интерфейса и наоборот?Я видел метод getEnv, но я не знаю, как его использовать ...

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

getEnv() - это способ получить доступ к некоторым переменным среды (, которые вы ранее передали корневому узлу ) из любого узла в MST независимо от глубины ( думаю, Context в React ).

При создании нового дерева состояний можно передавать данные, специфичные для окружающей среды, передавая объект в качестве второго аргумента в вызов .create.Этот объект должен быть (мелко) неизменным и может быть доступен для любой модели в дереве, вызывая getEnv(self).Это полезно для внедрения среды или специфичных для тестирования утилит, таких как транспортный уровень, регистраторы и т. Д.

Очень удобно, но, похоже, не то, что вам нужно.

ТамЕсть много разных способов прохождения MST.Например, вы можете присвоить уникальный идентификатор любому узлу, а затем получить его из любого другого узла в MST.

Вы также можете использовать getRoot (self) , getParent (self, deep = 1) или getParentOfType (self, type) помогает пройти по дереву вверх от заданного узла.

Но самый простой подходв вашем случае будет использовать resolPath (узел, путь) .Таким образом, в основном из любого вида или действия в data вы можете сделать:

import { types as t, resolvePath } from 'mobx-state-tree'

// ...

resolvePath(self, '../ui').activeCategory
0 голосов
/ 25 февраля 2019

Самый простой подход состоит в том, чтобы вызывающий 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 может быть дочерним по отношению к пользовательскому интерфейсу.Мне не очень нравится этот подход, хотя в большинстве случаев.

Последнее решение ... Родитель этих двух хранилищ может предоставлять представления, использующие как пользовательский интерфейс, так и данные.Хотя это может привести к раздутой модели. Ни одно из этих решений не является идеальным, поэтому мне любопытно посмотреть, какие еще ответы появятся.

...