在 Elm 的数据列表中创建新记录
Create a New Record in a List of data in Elm
我在 Elm 中完成了从 API 加载资源,一切都很好...除了一个小问题:我不知道如何在不保留它的情况下更新或创建新记录。
我有一个 Msg 类型(我为这个演示剥离了一些代码)
type Msg
= NoOp
| FetchSucceed (List User)
| FetchError Http.Error
| UpdateTitle String
| ...
update msg model =
case model of
NoOp ->
( model, Cmd.none )
FetchSucceed newModel =
( { model | users = newModel, isLoading = False }, Cmd.none )
FetchError _ =
( { model | isLoading = False }, Cmd.none )
UpdateTitle newTitle =
-- I don't know what to put here, the previous messages
-- have a list, and I Just want to add ONE model
view model =
div []
[ List.map displayRow model.users
, formCreateUser {title = "", username = "", email = ""}
]
formCreateUser user =
div []
[ input [ onInput UpdateTitle, placeholder "Title" ] []
, button [ onClick SaveUser ] [ text "Save" ]
]
我希望能够从此表单 (formCreateUser) 添加新模型,但我不断收到此错误:
The 3rd element has this type:
VirtualDom.Node Msg
But the 4th is:
Html Link -> Html (String -> Msg)
edit2:添加一些上下文
如果我理解你的示例片段,你有一个显示现有用户列表的页面,并且你想要一个 "quick add" 表单,让你创建另一个仅给出标题的用户。我将举一个简单的例子来说明如何实现这一目标,希望它能对您 运行 遇到的问题有所启发。
我假设您的用户和模型目前看起来像这样:
type alias Model =
{ users : List User
, isLoading : Bool
}
type alias User =
{ title : String
, username : String
, email : String
}
既然你有那个快速添加表单,我认为你不想在他们点击提交之前添加新用户。记住这个概念,让我们更新模型以存储待处理的新用户标题:
type alias Model =
{ users : List User
, isLoading : Bool
, newUserTitle : Maybe String
}
现在我们可以相应地更改您的视图功能。由于我们要在文本框中显示键入的标题,所以我们将 formCreateUser
更改为:
formCreateUser model =
div []
[ input [ onInput UpdateTitle, placeholder "Title", value (Maybe.withDefault "" model.newUserTitle) ] []
, button [ onClick SaveUser ] [ text "Save" ]
]
也就是说view
中的调用代码也需要更新:
view model =
div []
[ div [] (List.map displayRow model.users)
, formCreateUser model
]
现在我们需要处理 UpdateTitle
消息以在键入时设置内容:
UpdateTitle newTitle ->
( { model | newUserTitle = Just newTitle }, Cmd.none )
现在我们还可以处理提交按钮。这是您创建新用户并将其附加到现有用户列表的地方:
SaveUser ->
case model.newUserTitle of
Nothing -> (model, Cmd.none)
Just title ->
( { model
| newUserTitle = Nothing
, users = model.users ++ [{ title = title, username = "", email = "" }]
}, Cmd.none)
如果您希望 SaveUser
将其提交到您的 API 端点,您还可以 return 一个合适的 Cmd
,但这似乎超出了您的范围问题。
虽然这一切都不是处理您的情况的理想方式,但希望这种解释能让您更好地理解此类事情所需的构建块。我已经发布了 full gist here which can be pasted and run in elm-lang.org/try.
我在 Elm 中完成了从 API 加载资源,一切都很好...除了一个小问题:我不知道如何在不保留它的情况下更新或创建新记录。
我有一个 Msg 类型(我为这个演示剥离了一些代码)
type Msg
= NoOp
| FetchSucceed (List User)
| FetchError Http.Error
| UpdateTitle String
| ...
update msg model =
case model of
NoOp ->
( model, Cmd.none )
FetchSucceed newModel =
( { model | users = newModel, isLoading = False }, Cmd.none )
FetchError _ =
( { model | isLoading = False }, Cmd.none )
UpdateTitle newTitle =
-- I don't know what to put here, the previous messages
-- have a list, and I Just want to add ONE model
view model =
div []
[ List.map displayRow model.users
, formCreateUser {title = "", username = "", email = ""}
]
formCreateUser user =
div []
[ input [ onInput UpdateTitle, placeholder "Title" ] []
, button [ onClick SaveUser ] [ text "Save" ]
]
我希望能够从此表单 (formCreateUser) 添加新模型,但我不断收到此错误:
The 3rd element has this type:
VirtualDom.Node Msg
But the 4th is:
Html Link -> Html (String -> Msg)
edit2:添加一些上下文
如果我理解你的示例片段,你有一个显示现有用户列表的页面,并且你想要一个 "quick add" 表单,让你创建另一个仅给出标题的用户。我将举一个简单的例子来说明如何实现这一目标,希望它能对您 运行 遇到的问题有所启发。
我假设您的用户和模型目前看起来像这样:
type alias Model =
{ users : List User
, isLoading : Bool
}
type alias User =
{ title : String
, username : String
, email : String
}
既然你有那个快速添加表单,我认为你不想在他们点击提交之前添加新用户。记住这个概念,让我们更新模型以存储待处理的新用户标题:
type alias Model =
{ users : List User
, isLoading : Bool
, newUserTitle : Maybe String
}
现在我们可以相应地更改您的视图功能。由于我们要在文本框中显示键入的标题,所以我们将 formCreateUser
更改为:
formCreateUser model =
div []
[ input [ onInput UpdateTitle, placeholder "Title", value (Maybe.withDefault "" model.newUserTitle) ] []
, button [ onClick SaveUser ] [ text "Save" ]
]
也就是说view
中的调用代码也需要更新:
view model =
div []
[ div [] (List.map displayRow model.users)
, formCreateUser model
]
现在我们需要处理 UpdateTitle
消息以在键入时设置内容:
UpdateTitle newTitle ->
( { model | newUserTitle = Just newTitle }, Cmd.none )
现在我们还可以处理提交按钮。这是您创建新用户并将其附加到现有用户列表的地方:
SaveUser ->
case model.newUserTitle of
Nothing -> (model, Cmd.none)
Just title ->
( { model
| newUserTitle = Nothing
, users = model.users ++ [{ title = title, username = "", email = "" }]
}, Cmd.none)
如果您希望 SaveUser
将其提交到您的 API 端点,您还可以 return 一个合适的 Cmd
,但这似乎超出了您的范围问题。
虽然这一切都不是处理您的情况的理想方式,但希望这种解释能让您更好地理解此类事情所需的构建块。我已经发布了 full gist here which can be pasted and run in elm-lang.org/try.