【问题标题】:Creating nested models on the fly using types.reference in mobx-state-tree使用 mobx-state-tree 中的 types.reference 动态创建嵌套模型
【发布时间】:2020-04-05 22:14:04
【问题描述】:

我有几个相互引用的模型。这是一个例子。

export const AlbumModel = types
  .model("Album")
  .props({
    id: types.identifier,
    name: types.string,
    artists: types.array(ArtistModel),
    uri: types.string,
    releaseDate: types.maybe(types.string),
    images: types.array(types.maybe(ImageModel))
  })

export const ArtistModel = types
  .model("Artist")
  .props({
    id: types.identifier,
    name: types.string,
    uri: types.string
  })

export const ImageModel = types
  .model("Image")
  .props({
    url: types.identifier,
    width: types.maybe(types.number),
    height: types.maybe(types.number)
  })

然后,当我去创建专辑时,我会这样做:

Album.create({
  id: '12345',
  name: 'My Cool Album',
  artists: [{
    id: '67890',
    name: 'Mr. Bean',
    uri: 'https://my-cool-site.com/artist/mr-bean'
  }],
  uri: 'https://my-cool-site.com/album/my-cool-album',
  releaseDate: '12-12-2012',
  images: [{
    url: 'https://my-cool-site.com/pic/1'
  }]  
})

这很好用,但是当我从服务中获取数据时,我会得到一堆我想插入 mst 的 JSON。当我这样做时,我正在创建重复的艺术家和图像。

问题 有没有一种(简单的)方法可以即时创建艺术家和图像,并将它们作为参考传递给专辑模型。还是我需要编写一个单独的函数来创建图像和艺术家,将它们粘贴到树中,然后将它们作为专辑的一部分引用?

我尝试了什么

export const AlbumModel = types
  .model("Album")
  .props({
    id: types.identifier,
    name: types.string,
    artists: types.array(types.reference(ArtistModel)),
    uri: types.string,
    releaseDate: types.maybe(types.string),
    images: types.array(types.maybe(types.reference(ImageModel)))
  })

抛出以下错误:

at path "/images/0" snapshot `{"height":300,"url":"https://my-cool-site.com/pic/1","width":300}` is not assignable to type: `(reference(Image) | undefined)` (No type is applicable for the union), expected an instance of `(reference(Image) | undefined)` or a snapshot like `(reference(Image) | undefined?)` instead.

【问题讨论】:

  • 您找到解决方案了吗?
  • @SaschaGehlich - 没有。我必须手动编写一个函数来检查是否存在具有相同 id 的模型,如果不存在,它将创建模型,然后将其作为参考传递。我觉得这应该融入 mst

标签: mobx-state-tree


【解决方案1】:

不确定这是否可行,但值得一试

如果你把它放在 AlbumModel 艺术家中

    types.reference(ArtistModel, {
        // given an identifier, find the user
        get(artist /* string */, parent: any /*AlbumModel*/) {
            return parent.artists.find(a => a.id === artist.id) || ArtistModel.create(data)
        },
        // given a user, produce the identifier that should be stored
        set(artist /* ArtistModel */) {
            return artist.id
        }
    })

这个想法最初是尝试查找艺术家是否已经存在,如果不存在,它将创建一个新的 ArtistModel。

如果可行,请告诉我:)

【讨论】:

  • 当我这样做时,MST 仍然在抱怨我试图将快照传递给引用类型字段
猜你喜欢
  • 2020-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-06
  • 2019-11-26
  • 1970-01-01
相关资源
最近更新 更多