Как я могу клонировать наблюдаемый объект MobX? (редактировать, сохранять изменения)

#reactjs #mobx

#reactjs #mobx

Вопрос:

У меня есть простая форма react и два наблюдаемых объекта в моем хранилище MobX:

 @observable personalInfo = {
        email: '',
        gender: 1,
        birthDate: null, 
        location: ''
    };
@observable personalInfoInEdit = null;
  

Когда форма личной информации загружена (в ctor) Я вызываю метод в моем хранилище:

 reset_PersonalInfoInEdit() {
        this.personalInfoInEdit = observable(this.personalInfo);
}
  

То, что он дозирует, просто сбрасывает объект «в редактировании», заполняя его данными из исходных данных. Если пользователь нажмет «Сохранить изменения», объект «в редактировании» будет скопирован в оригинал.

Допустим ли вызов observable () с другим наблюдаемым объектом? Какие-либо побочные эффекты к этому? (кажется, это работает)

И если нет, существуют ли шаблоны проектирования для элегантной обработки этого сценария объекта «в редактировании».

Комментарии:

1. AFAIK, это нормально. Но чтобы убедиться, cc @mweststrate

2. Вы не можете просто сделать это.personalInfoInEdit = this.PersonalInfo

Ответ №1:

Предпочтительным шаблоном было бы использовать служебную функцию createViewModel из mobx-utils. Итак, вы бы сделали:

 import { createViewModel } from 'mobx-utils'

reset_PersonalInfoInEdit() {
    this.personalInfoInEdit = createViewModel(this.personalInfo);
}
  

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

 class Todo {
  @observable title = "Test"
}

const model = new Todo()
const viewModel = createViewModel(model);

autorun(() => console.log(viewModel.model.title, ",", viewModel.title))
// prints "Test, Test"
model.title = "Get coffee"
// prints "Get coffee, Get coffee", viewModel just proxies to model
viewModel.title = "Get tea"
// prints "Get coffee, Get tea", viewModel's title is now dirty, and the local value will be printed
viewModel.submit()
// prints "Get tea, Get tea", changes submitted from the viewModel to the model, viewModel is proxying again
viewModel.title = "Get cookie"
// prints "Get tea, Get cookie" // viewModel has diverged again
viewModel.reset()
// prints "Get tea, Get tea", changes of the viewModel have been abandoned
  

Комментарии:

1. Ух ты, я понятия не имел, что такое существует. Хотелось бы, чтобы это было в основной документации Mobx.

2. Будьте внимательны! createViewModel это изящный трюк, но он сопряжен с некоторыми недостатками, в том числе невозможностью ссылаться на вычисленные свойства модели.

3. Как насчет вложенных свойств, например viewModel.list[i].name ? Возможно ли получить «рекурсивную» viewmodel? Кроме того, иногда нам действительно просто нужен клон.