2017-03-14 130 views
2

我想玩elmplayground的源代碼,我試圖爲博客創建配置json文件。我現在遇到的問題是,我不知道如何才能將帖子/頁面作者解碼爲嵌套結構。我想要的是帖子和頁面中的author字段對config.json中的作者進行引用。解碼嵌套的JSON結構

config.json:

{ 
    "posts": [{ 
    "slug": "/hello-world", 
    "title": "Hello World", 
    "name": "hello-world", 
    "publishedDate": "2016-10-30", 
    "author": "Gabriel", 
    "intro": "" 
    }], 
    "pages": [{ 
    "slug": "/hello", 
    "name": "index", 
    "title": "Elm Playground", 
    "publishedDate": "2016-09-01", 
    "author": "Gabriel", 
    "intro": "" 
    }], 
    "authors": { 
    "Gabriel": { 
     "name": "Gabriel Perales", 
     "avatar": "..." 
    } 
    } 
} 

頁面和崗位類型的內容:

type alias Content = 
    { title : String 
    , name : String 
    , slug : String 
    , publishedDate : Date 
    , author : Author 
    , markdown : WebData String 
    , contentType : ContentType 
    , intro : String 
    } 

類型作者:

type alias Author = 
    { name : String 
    , avatar : String 
    } 

目前,這是我的配置解碼器:

configDecoder : Decoder Config 
configDecoder = 
    Decode.map2 Config 
     (field "posts" <| Decode.list <| decodeContent Post) 
     (field "pages" <| Decode.list <| decodeContent Page) 

decodeContent : ContentType -> Decoder Content 
decodeContent contentType = 
    Decode.map8 Content 
     (field "slug" string) 
     (field "name" string) 
     (field "title" string) 
     (field "publishedDate" decodeDate) 
     (field "author" 
      (string 
       -- I want to decode the author from "authors" 
       -- I have tried with 
       -- (\name -> at ["authors", name] decodeCofigAuthor) but it doesn\'t work 
       |> andThen (\name -> Decode.succeed <| Author name "...") 
      ) 
     ) 
     (Decode.succeed RemoteData.NotAsked) 
     (Decode.succeed contentType) 
     (field "intro" string) 


decodeConfigAuthor : Decoder Author 
decodeConfigAuthor = 
    Decode.map2 Author 
     (field "name" string) 
     (field "avatar" string) 

回答

3

我會先解碼作者,然後用andThen將作者Dict轉換爲decodeContent。然後,您可以使用Decode.map將作者姓名轉換爲authorsDict中的查找。

decoder = 
    (field "authors" <| Decode.dict <| authorDecoder) 
     |> Decode.andThen configDecoder 

configDecoder authors = 
    Decode.map2 Config 
     (field "posts" <| Decode.list <| decodeContent Post authors) 
     (field "pages" <| Decode.list <| decodeContent Page authors) 

decodeContent contentType authors = 
    Decode.map8 Content 
     -- … 
     (field "author" (string |> Decode.map (\name -> Dict.get name authors))) 
     -- … 

這會改變你的模型使用Maybe Author,但你也可以使用Decode.andThen並返回Decode.fail如果Dict.get回報Nothing

+0

我要試一試,但它看起來像我一直在尋找 – gabrielperales