Как я могу применить снимок с другим типом? - PullRequest
0 голосов
/ 30 октября 2019

Я использую различные типы моделей "Todo" в своем приложении. Типы реализуются через поле с именем «type».

const BaseTodo = types
  .model("BaseTodo", {
    id: types.optional(types.number, () => Math.random()),
    title: types.string,
    finished: false,
    type: types.string
  })
  .actions(self => ({
    toggle() {
      self.finished = !self.finished;
    },
    changeToShoppingType() {
      const snap = getSnapshot(self);
      console.log("snapshot: ", snap);
      const newSnap = {};
      Object.assign(newSnap, snap, { type: "shopping" });

      console.log("newSnap: ", newSnap);
      applySnapshot(self, newSnap);
      console.log("after apply snap: ", self);
    }
  }));

const ShoppingTodo = BaseTodo.named("ShoppingTodo").props({
  type: types.literal("shopping")
});

const CleaningTodo = BaseTodo.named("CleaningTodo").props({
  type: types.literal("cleaning")
});

export const Todo = types.union(ShoppingTodo, CleaningTodo);

export const TodoStore = types
  .model("TodoStore", {
    todos: types.array(Todo)
  });

Моя проблема: когда я хочу изменить тип шага с «очистки» на «покупки», применив снимок к моему объекту, яполучаю ошибку:

... по пути "/ type" значение "shopping" не присваивается типу: "cleaning"

Любая подсказка, как реализовать моиusecase?

Я создал пример кода и ящика того, как я хочу изменить тип (просто нажмите кнопку): https://dm71z.csb.app/

К сожалению, я не могу получить ошибку, чтобы показать вконсоль.

1 Ответ

1 голос
/ 02 ноября 2019

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

Итак, что вам нужносделать, чтобы TodoStore заменил todo:

export const TodoStore = types
  .model("TodoStore", {
    todos: types.array(Todo),
  })
  .actions(self => ({
    changeToShoppingType: (todo) => {
      const snap = getSnapshot(todo);
      console.log("snapshot: ", snap);
      const newSnap = {};
      Object.assign(newSnap, snap, { type: "shopping" });

      console.log("newSnap: ", newSnap);
      self.todos.splice(self.todos.indexOf(todo), 1, newSnap);
    }
  }));

Проверьте этот пример https://codesandbox.io/s/simple-mobx-todolist-m8bre?fontsize=14.

...