表单
我们现在将制作一个简单的表单。它有一个字段用于输入姓名、一个字段用于输入密码,以及一个字段用于验证该密码。我们还将执行一些非常简单的验证操作以检查密码是否匹配。
我在下面包含了完整的程序。点击蓝色的“编辑”按钮在在线编辑器中对其进行处理。尝试引入错字以查看一些错误消息。尝试拼错记录字段(比如 password
)或函数(比如 placeholder
)。立即点击蓝色按钮!
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onInput)
-- MAIN
main =
Browser.sandbox { init = init, update = update, view = view }
-- MODEL
type alias Model =
{ name : String
, password : String
, passwordAgain : String
}
init : Model
init =
Model "" "" ""
-- UPDATE
type Msg
= Name String
| Password String
| PasswordAgain String
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 }
-- VIEW
view : Model -> Html Msg
view model =
div []
[ viewInput "text" "Name" model.name Name
, viewInput "password" "Password" model.password Password
, viewInput "password" "Re-enter Password" model.passwordAgain PasswordAgain
, viewValidation model
]
viewInput : String -> String -> String -> (String -> msg) -> Html msg
viewInput t p v toMsg =
input [ type_ t, placeholder p, value v, onInput toMsg ] []
viewValidation : Model -> Html msg
viewValidation model =
if model.password == model.passwordAgain then
div [ style "color" "green" ] [ text "OK" ]
else
div [ style "color" "red" ] [ text "Passwords do not match!" ]
这与我们的文本字段示例非常相似,但字段更多。
模型
我总是从猜测 Model
开始。我们知道会有三个文本字段,那么我们直接开始做吧
type alias Model =
{ name : String
, password : String
, passwordAgain : String
}
我通常尝试从最简单的模型开始,可能就一个字段。然后尝试编写 view
和 update
函数。这通常会表明我需要向我的 Model
中添加更多内容。像这样逐步构建模型意味着我在整个开发过程中都可以获得一个正常工作的程序。它可能还没有所有功能,但正在完善中!
更新
有时你会对基本更新代码的样子有一个非常好的想法。我们知道我们需要能够更改三个字段,所以我们需要为每种情况设定消息。
type Msg
= Name String
| Password String
| PasswordAgain String
这意味着我们的 update
需要为这三个变体设定情况
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 }
每个情况都使用记录更新语法来确保转换相应的字段。这与之前的示例类似,只是情况更多。
不过,我们的 view
有点比平常花哨。
视图
这个 view
函数正在使用帮助程序函数来让事情更有条理
view : Model -> Html Msg
view model =
div []
[ viewInput "text" "Name" model.name Name
, viewInput "password" "Password" model.password Password
, viewInput "password" "Re-enter Password" model.passwordAgain PasswordAgain
, viewValidation model
]
在之前的示例中,我们直接使用 input
和 div
。我们为什么要停?
HTML 在 Elm 中很简洁,因为input
和div
只是普通函数。它们需要(1)一个属性列表和(2)一个子节点列表。由于我们使用的是一般的 Elm 函数,因此,我们可以充分利用 Elm 的强大功能构建我们的视图!我们可以将重复的代码重构为自定义的辅助函数。这正是我们在这里所做的!
因此,我们的view
函数对viewInput
有三个调用
viewInput : String -> String -> String -> (String -> msg) -> Html msg
viewInput t p v toMsg =
input [ type_ t, placeholder p, value v, onInput toMsg ] []
这意味着在 Elm 中编写viewInput "text" "Name" "Bill" Name
将在屏幕上显示时变成一个 HTML 值,例如<input type="text" placeholder="Name" value="Bill">
。
第四个条目更有趣。这是对viewValidation
的调用
viewValidation : Model -> Html msg
viewValidation model =
if model.password == model.passwordAgain then
div [ style "color" "green" ] [ text "OK" ]
else
div [ style "color" "red" ] [ text "Passwords do not match!" ]
此函数首先比较两个密码。如果它们匹配,您将得到绿色的文本和正面的消息。如果不匹配,您将得到红色的文本和一条有用的消息。
这些辅助函数开始显示拥有普通 Elm 代码的 HTML 库的好处。我们可以将所有这些代码放入我们的view
中,但在 Elm 中创建辅助函数是完全正常的,即使在视图代码中也是如此。“这变得难以理解了吗?也许我可以分解一个辅助函数!”
练习:在在线编辑器中查看此示例此处。尝试向
viewValidation
辅助函数添加以下功能
- 检查密码的长度是否大于 8 个字符。
- 确保密码包含大写、小写和数字字符。
在这些练习中使用来自
String
模块的函数!警告:在我们开始发送 HTTP 请求之前,我们需要了解更多知识。在亲自尝试之前,请继续阅读直至 HTTP 部分。在适当的指导下,这将变得容易得多!
注意:创建通用的验证库的努力似乎并不太成功。我认为问题在于,检查通常最好通过普通的 Elm 函数来捕获。使用一些参数向后发送
Bool
或Maybe
。例如:为什么使用库来检查两个字符串是否相等?因此,据我们所知,最简单的代码来自于为您的特定情况编写逻辑,而无需任何特殊额外内容。因此,在确定您需要更复杂的内容之前,务必尝试一下!