Наблюдаемый MobX с динамическими данными

У меня следующий класс

export default class BaseStore {
  @observable model ;

  @action updateStore(propertyName, newValue) {
    this.model[propertyName] = newValue;
  }
}

В дочерних классах я добавляю слои к наблюдаемой модели, например:

model.payment.type = 'credit card'

Мой компонент реакции не отображается автоматически, когда это происходит, однако, если у меня есть данные верхнего уровня, такие как:

model.Type = 'CreditCard'

Я новичок в MobX и прочитал, что мне нужно использовать map (), но я не могу найти достойный пример, объясняющий, как его использовать.


person Pacman    schedule 31.08.2017    source источник
comment
Что вы имеете в виду, когда говорите: «В дочерних классах я добавляю слои к наблюдаемой модели»? Не могли бы вы поделиться точными фрагментами кода, которые добавляют в модель слои?   -  person Alik    schedule 02.09.2017


Ответы (1)


Если вы знаете все ключи, которые будет иметь model, вы можете просто инициализировать их значением null, и компоненты observer будут повторно визуализированы.

Пример (JSBin)

class BaseStore {
  @observable model = {
    type: null
  };

  @action updateStore(propertyName, newValue) {
    this.model[propertyName] = newValue;
  }
}

const baseStore = new BaseStore();

@observer
class App extends Component {
  componentDidMount() {
    setTimeout(() => baseStore.model.type = 'CreditCard', 2000);
  }

  render() {
    return <div> { baseStore.model.type } </div>;
  }
}

Если вы не знаете заранее все ключи model, вы можете использовать карту < / strong> как вы сказали:

Пример (JSBin)

class BaseStore {
  model = observable.map({});

  @action updateStore(propertyName, newValue) {
    this.model.set(propertyName, newValue);
  }
}

const baseStore = new BaseStore();

@observer
class App extends Component {
  componentDidMount() {
    this.interval = setInterval(() => {
      const key = Math.random().toString(36).substring(7);
      const val = Math.random().toString(36).substring(7);
      baseStore.updateStore(key, val);
    }, 1000);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    return <div> 
      { baseStore.model.entries().map(e => <div> {`${e[0]} ${e[1]}` } </div>) } 
    </div>;
  }
}
person Tholle    schedule 01.09.2017
comment
Моя проблема связана с более глубокими элементами, такими как: model.input.card.number // в качестве примера в этом случае не запускается функция Render - person Pacman; 01.09.2017
comment
Я начинаю с простой модели и хочу, чтобы во время выполнения началось добавление таких элементов, как эта иерархия: model.Payment.CreditCard.Amount. И я хочу, чтобы мой рендер запускался, когда я изменяю количество, хотя у исходного наблюдателя этот элемент был только позже в жизненном цикле программы. - person Pacman; 05.09.2017