我一直在关注本教程:http://guide.elm-lang.org/architecture/user_input/forms.html
那里的文字对我有意义,我的问题与它在页面底部列出的练习有关。它问我:
“为年龄添加其他字段并检查它是否为数字。”
我遇到这个问题很困难,因为onInput
函数似乎只接受String输入。我觉得很奇怪,type="number"
输入没有等价物。
然而,这是我的尝试不起作用:
import Html exposing (..)
import Html.App as Html
import Html.Attributes exposing (..)
import Html.Events exposing (onInput)
import String exposing (length)
main =
Html.beginnerProgram { model = model, view = view, update = update }
-- MODEL
type alias Model =
{ name : String
, password : String
, passwordAgain : String
, age : Int
}
model : Model
model =
Model "" "" "" 0
-- UPDATE
type Msg
= Name String
| Password String
| PasswordAgain String
| Age Int
update : Msg -> Model -> Model
update msg model =
case msg of
Name name ->
{ model | name = name }
Password password ->
{ model | password = password }
PasswordAgain password ->
{ model | passwordAgain = password }
Age age ->
{ model | age = age }
-- VIEW
view : Model -> Html Msg
view model =
div []
[ input [ type' "text", placeholder "Name", onInput Name ] []
, input [ type' "password", placeholder "Password", onInput Password ] []
, input [ type' "password", placeholder "Re-enter Password", onInput PasswordAgain ] []
, input [ type' "number", placeholder "Age", onInput Age ] []
, viewValidation model
]
viewValidation : Model -> Html msg
viewValidation model =
let
(color, message) =
if model.password /= model.passwordAgain then
("red", "Passwords do not match!")
else if length model.password <= 8 then
("red", "Password must be more than 8 characters!")
else
("green", "OK")
in
div [ style [("color", color)] ] [ text message ]
我得到的错误如下:
-- TYPE MISMATCH ----------------------------------------------------- forms.elm
The argument to function `onInput` is causing a mismatch.
58| onInput Age
^^^
Function `onInput` is expecting the argument to be:
String -> a
But it is:
Int -> Msg
注意:我知道我可以创建Age输入作为另一个文本输入,但练习特别要求我检查它是一个`数字类型。我认为这意味着我应该把它作为Int。
保存在模型中我很清楚错误是什么。我只是想知道在Elm中解决这个问题的惯用方法。感谢。
答案 0 :(得分:6)
来自onInput
事件的任何用户输入都是字符串。
您的Model
期望它是Int
使用String.toInt从字符串值中解析整数值。
调整update
功能,将类型转换为Int
,并将类型签名更改为Age String
Age age ->
case String.toInt age of
Ok val ->
{ model | age = val }
-- Notify the user, or simply ignore the value
Err err ->
model
通过这种方式,您可以选择通知用户错误。
如果Maybe
值更适合您,整个陈述可以简化为:
Age age ->
{ model | age = Result.toMaybe (String.toInt age) }
答案 1 :(得分:1)
你需要相当于onInput
,但对于整数运算。根据{{1}}的定义方式,您可以通过添加targetValue
来执行类似的操作,将其解析为整数:
Json.Decode.int
然后您可以这样使用它:
onIntInput : (Int -> msg) -> Attribute msg
onIntInput tagger =
Html.Events.on "input" (Json.map tagger (Json.at ["target", "value"] Json.int))