我发现将旧的Model状态迁移到新的Model状态非常困难。如何编写一个JSON解码器,将类型ModelV1转换为类型ModelV2
假设我们的代码最初有Model,并且我们坚持它到本地存储。
现在我们要为我们的模型添加一个额外的字段“createdAt”,所以我为此创建了一个新的类型别名。
import Json.Decode as D
import Html as H
type alias Todo = {id:Int, title: String}
jsonV1 = """
{"id":1, "title":"Elm-Rocks"}
"""
jsonV2 = """
{"id":1, "title":"Elm-Rocks", "createdAt":1479633701604}
"""
type alias TodoV2 = {id:Int, title: String, createdAt:Int}
decode = D.map2 Todo
(D.field "id" D.int)
(D.field "title" D.string)
decodeV2 = D.map3 TodoV2
(D.field "id" D.int)
(D.field "title" D.string)
(D.field "createdAt" D.int)
result1 = D.decodeString decode jsonV1
result2 = D.decodeString decodeV2 jsonV2
type alias Model = {todos: List Todo}
type alias ModelV2 = {todos: List TodoV2}
main = H.div[] [
H.div[][H.text (toString result1)]
, H.div[][H.text (toString result2)]
]
如何写一个解码器/函数,接受任何V1/V2格式的JSON字符串,并给我一个ModelV2
记录。
我知道Decoder.andThen,但我不知道怎么写了todoDecoderV1: ??? -> TodoV2
我正在经历“不可能的状态”的谈话,还没有完成它。 但createdAt不是一个可选字段,我不希望在代码中放置可能的检查。你是否暗示每次模式改变时,我都会使用?这将是一个难题。由于新代码被保证在产生有效的创建。此解码仅在模式迁移过程中完成。 – Jigar
这是可以理解的。如果您选择走这条路线,您只需要一个合理的默认值。在我的第一个'oneOf'示例中,我使用了零,但您可以使用任何适合您的业务需求的东西。 –