首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >mobx-state-tree支持嵌套模型吗?

mobx-state-tree支持嵌套模型吗?
EN

Stack Overflow用户
提问于 2020-02-26 18:29:56
回答 1查看 1K关注 0票数 0

我有一个父模型和一个状态-子模型,并且我希望在子模型中引用item.pdf.download()这样的操作。

我已经创建了一个解决方法:

代码语言:javascript
复制
const pdf = types.model({ state: ... })
const Item = types.model({ ... }).volatile(self => ({ pdf: pdf.create({ ... }) }))

但它看起来不像是预期的方式,

有没有办法在mobx-state-tree中做嵌套模块?

EN

回答 1

Stack Overflow用户

发布于 2020-08-12 18:14:25

是的,事实上,所有不是原语的东西都需要是某个MST模型,才能成为更大模型的一部分

代码语言:javascript
复制
// Parent
const ItemModel = types.model({
  pdf: types.optional(PdfModel, {}),
  // or when the child needs an initial data not provided by the snapshot
  // pdf: types.optional(PdfModel, { state: 'initial' }),

  // It can ofcourse be a list (or map) of child types, default value is []
  relatedPdfs: types.array(PdfModel),
})
  .views(self => ({
    get downloaded() {
      return self.relatedPdfs.filter(pdf => pdf.state == 'complete');
    }
  }))
  .actions(self => ({
    async downloadAll() {
      const tasks = self.relatedPdfs.map(pdf => pdf.download());
      const results = await Promise.all(tasks);

      return results;
    }),
  }));

// Child
const PdfModel = types.model({
  state:  types.optional(types.enumeration(['initial', 'downloading', 'complete', 'error']), 'initial'),
  url: types.maybeNull(types.string),
})
  .volatile(self => ({
    data: null,
  })),
  .actions(self => ({
    download: flow(function * download(url = self.url) {
      self.state = 'downloading';
      
      try {
        const data = await downloadTheData(url);
        
        self.state = 'complete';
        self.data = data;
       
        return data;
      }
      catch(e) {
        self.state = 'error';
      }
    }),
  }));

可能出现的问题是,当您创建parent类型的实例时,您可能必须提供整个树的快照,或者通过types.optional()为任何子类型定义默认值,或者通过types.maybe允许undefined/null

例如,如果我们没有子值的types.optionaltype.maybeNull,我们就必须提供一个涵盖这一点的快照

代码语言:javascript
复制
  const snap = {
    pdf: { state: 'initial', url: 'http://example.com' },
  };

  const item = ItemModel.create(snap);

但是由于我们已经覆盖了默认值,所以我们不需要初始快照

代码语言:javascript
复制
 const item = ItemModel.create();

当然,您也可以提供快照来覆盖默认设置

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60411801

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档