Обновление вложенной записи новыми данными в elm - PullRequest
0 голосов
/ 29 октября 2018

У меня есть две части JSON, которые я успешно декодировал последовательно. Я хотел бы взять новый html_fragment и обновить свой существующий html_fragment. Обычно это было бы просто, но моя структура данных доставляет мне трудности:

type PostDataContainer
    = PostDataContainer PostData


type alias PostData =
    { title : String
    , comments : List Comment
    }


type alias Comment =
    { comment_id : Int
    , html_fragment : String
    }


type alias CommentHtml =
    { id : Int
    , html_fragment : String
    }

Я только что получил CommentHtml и хотел бы обновить существующий html_fragment в Comment. Это то, что я до сих пор:

    MergeCommentHtml commentHtmlData ->
        case commentHtmlData of
            Err err ->
                Debug.log ("Error decoding CommentHtmlData" ++ toString err)
                    ( mdl, Cmd.none )

            Ok commentHtml ->
                case mdl.maybePostDataContainer of
                    Just (PostDataContainer postData) ->
                        let
                            updatedCommentData = -- I dont know how to calculate this?
                        in
                        ( { mdl | postData = { postData | comments = updatedCommentData } }, Cmd.none )

Обратите внимание, что commentHtml здесь List CommentHtml. Любые мысли о том, как обновить мой старый comment.html_fragment с новыми значениями в commentHtml?

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Учитывая, что commentHtmlData является List согласно комментарию, я думаю, что самый простой подход - преобразовать его в Dict с ключом id, а затем отобразить существующие комментарии в поисках comment_id в диктанке. Если он существует, замените html_fragment, если нет, то верните исходное неизмененное:

let
    commentHtmlDict =
        commentHtmlData
            |> List.map (\c -> (c.id, c))
            |> Dict.fromList

    updatedCommentData =
        postData.comments
            |> List.map (\comment ->
                case Dict.get comment.comment_id commentHtmlDict of
                    Just commentHtml ->
                        { comment | html_fragment = commentHtml.html_fragment }

                    Nothing ->
                        comment
            )
0 голосов
/ 29 октября 2018

Вариант 1: просто расшифруйте данные как есть. Когда пришло время отобразить его, расположите его соответствующим образом с помощью некоторой функции, которую вы напишите, например rawJsonDataToNicerData.

Вариант 2:
Предположим, вы реализуете следующую функцию:

-- given a new comment, and some PostData, return the new version of the PostData
updateData : CommentHtml -> PostData -> PostData

-- so now, assuming we can decode a CommentHtml with commentHtmlDeocder
-- we can do the following
dataUpdaterDecoder : Decoder (PostData -> PostData)
dataUpdaterDecoder 
   commentHtmlDecoder |> Decoder.andThen (\commentHtml -> updateData commentHtml)

Теперь, куда бы мы ни собирались декодировать commentHtmlDeocder, мы можем вместо этого декодировать dataUpdaterDecoder и использовать их для обновления наших данных.

Вот пример реляционного декодера данных в действии, использующего идею выше:

https://ellie -app.com / 3KWmyJmMrDsa1

...