Создание вложенных моделей на лету с использованием types.reference в mobx-state-tree - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть несколько моделей, которые ссылаются друг на друга. Вот пример.

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)
  })

Затем, когда я go создаю альбом, я делаю что-то вроде этого:

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'
  }]  
})

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

Вопрос Есть ли способ (simple-i sh), позволяющий создавать художников и изображения на лету? и передайте их как ссылку на модель альбома. Или мне нужно написать отдельную функцию, которая будет создавать изображения и художников, вставлять их в дерево, а затем ссылаться на них как на часть альбома?

Что я пробовал :

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.

1 Ответ

0 голосов
/ 10 апреля 2020

Не уверен, что это сработает, но стоит попробовать

Если вы добавите это в 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.

Пожалуйста, дайте мне знать, если это работает:)

...