如何在Elm中将html-input解码为int?

Fak*_*ish 0 parsing decode input elm

有html输入.我们监听输入事件并更新模型(这里是简单的字符串).现在我想将Int类型用于模型,并从输入值中解析Int.我做了另一个解码器,并将初始模型的值更改为0.在我输入数字后,这些更改模型不会更改.为什么?怎么实现呢?

import Html exposing (input, div, text)
import Html.Events
import StartApp.Simple
import Json.Decode

model = ""

view address model =
  let

    decoder =
      Html.Events.targetValue

    -- this decoder doesn't work
    decoderInt =
      Json.Decode.at ["target", "value"] Json.Decode.int

  in
    div [] [
      input [ Html.Events.on "input" decoder (Signal.message address) ] [],
      text (toString model)
    ]

update action model =
  action

main =
  StartApp.Simple.start { model = model, view = view, update = update }
Run Code Online (Sandbox Code Playgroud)

Cha*_*ert 6

Json解码不起作用,因为Json值是一个字符串,即使字符串中的值是一个数字.例如,Json值看起来像这样:

{ "target": { "value": "42" } }
Run Code Online (Sandbox Code Playgroud)

榆树的Json解码功能非常严格,所以它们只会看到"42"一个字符串.您需要更进一步构建一个解析器,将该字符串的内部解析为数字 - 如果用户键入非数字的内容,则可能会失败.

为此,我们可以Html.Events.targetValue最初切换回使用解码器,因为它知道如何解码字符串值.然后我们通过它Json.Decode.andThen来提取该字符串的值并继续操作.

decoderInt =
  Html.Events.targetValue `Json.Decode.andThen` \str ->
    case String.toInt str of
      Ok i ->
        Json.Decode.succeed i
      Err msg ->
        Json.Decode.fail msg
Run Code Online (Sandbox Code Playgroud)

使用succeedfail将值重新映射到类型中Decoder Int.