json – 如何通过Elm端口传递联合类型?

我在尝试榆树时碰到了一个问题.我想通过端口传递一个union类型,但是我得到了这个错误
Port `setStorage` is trying to communicate an unsupported type.

34| port setStorage : Model -> Cmd msg
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The specific unsupported type is:

    Todo.Importance

The types of values that can flow through in and out of Elm include:

    Ints,Floats,Bools,Strings,Maybes,Lists,Arrays,Tuples,Json.Values,and concrete records.

修改了Todo example如下:

type alias Task =
    { description : String,completed : Bool,editing : Bool,id : Int,importance : Importance
    }

type Importance
  = normal
  | High
  | Low

这个issue似乎很老了.一位评论者建议“通过端口传递Json.Values和Json.Decode / Encode”但是如何做到这一点?文档似乎有点不清楚,缺乏完整的例子.任何帮助赞赏.

解决方法

我用Json.Decoder / Encoder制作了 work.毕竟不是那么困难,虽然必须序列化每一个字段只是为了通过一个联合类型是一个相当大的负担.

解码器:

modelDecoder : Json.Decoder Model
modelDecoder =
  Json.object4 Model
    ("tasks" := Json.list taskDecoder)
    ("field" := Json.string)
    ("uid" := Json.int)
    ("visibility" := Json.string)

taskDecoder : Json.Decoder Task
taskDecoder =
  Json.object5 Task
    ("description" := Json.string)
    ("completed" := Json.bool)
    ("editing" := Json.bool)
    ("id" := Json.int)
    ("importance" := Json.string `andThen` importanceDecoder)

importanceDecoder : String -> Json.Decoder Importance
importanceDecoder tag =
  case tag of
    "normal" -> Json.succeed normal
    "High" -> Json.succeed High
    "Low" -> Json.succeed Low
    _ -> Json.fail (tag ++ " is not a recognized tag for Importance")

和编码器:

modelTovalue : Model -> Json.Encode.Value
modelTovalue model =
  Json.Encode.object
    [
      ("tasks",Json.Encode.list (List.map taskTovalue model.tasks)),("field",Json.Encode.string model.field),("uid",Json.Encode.int model.uid),("visibility",Json.Encode.string model.visibility)
    ]

taskTovalue : Task -> Json.Encode.Value
taskTovalue task =
  Json.Encode.object
    [
      ("description",Json.Encode.string task.description),("completed",Json.Encode.bool task.completed),("editing",Json.Encode.bool task.editing),("id",Json.Encode.int task.id),("importance",importanceTovalue task.importance)
    ]

importanceTovalue : Importance -> Json.Encode.Value
importanceTovalue importance =
  case importance of
    normal -> Json.Encode.string "normal"
    High -> Json.Encode.string "High"
    Low -> Json.Encode.string "Low"

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...