xaviergonz / mobx-keystone

A MobX powered state management solution based on data trees with first class support for Typescript, support for snapshots, patches and much more
https://mobx-keystone.js.org
MIT License
549 stars 25 forks source link

Duplicate/clone an instance of a Model with a new $modelId #158

Closed toshimo closed 4 years ago

toshimo commented 4 years ago

Hi, I'm really impressed by how great this library is! I would say the keystone (and mobx) makes me more fun to code than other libraries.

Now, I'm wondering what is the right way to go if you want to duplicate an instance which has a different $modelId. I hope I'm not missing something. What I would like to do is something like this (simplified):

// in a model file
const initialParams = {
  // ...
};

@model("ItemModel")
class ItemModel extends Model({
  params: prop(() => initialParams),
}) {
  @action clone() {
    const clonedItem = this.......; // Maybe I can do something here?
    return clonedItem;
  }
}

@model('ArticleModel')
export class ArticleModel extends ExtendedModel(ItemModel, {}) {}

@model('PageModel')
export class PageModel extends ExtendedModel(ItemModel, {}) {}
// in a component file
export const ArticleComponent = (someList) => {
  const article = new ArticleModel({})

  const duplicate = () => {
    const clonedArticle = article.clone();
    someList.push(clonedArticle);
  };

  const create = () => {
    // ...
  };

  return (
    <>
      <div>Title: {article.title}</div>
      <button onClick={duplicate}> Duplicate </button>
      <button onClick={create}> Add new </button>
    </>
  );
};
Phault commented 4 years ago

You can easily clone an instance via snapshots. Take a look here for a helper method that does exactly that.

import { clone } from 'mobx-keystone';

const clonedArticle = clone(article);
toshimo commented 4 years ago

Oh my, apologies. I don't know why I wasn't able to find it. I gave it a shot and it exactly solved my problem. Thanks a lot!