我最近開始使用Elm,並遇到更新函數的問題。我的目標是將我的大文件Main.elm分割成多個較小的文件,但爲此我首先嚐試將主要組件拆分成同一文件中的較小組件。爲此,我非常依賴this very informative guide。在基本的Elm應用中重構更新功能
分割模型和init(我已經爲DiceRoller做過)是非常簡單的,對於View來說它是微不足道的。不幸的是,更新並不那麼重要。
目前,它看起來像這樣(在Main.elm文件的主分支)
type Msg = Change String
| Name String
| Password String
| PasswordAgain String
| Roll
| NewFace Int
| SearchImages
| NewSearchResult (Result Http.Error (List String))
| ChangeTermInput String
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Change newContent ->
({ model | content = newContent }, Cmd.none)
Name name ->
({ model | name = name }, Cmd.none)
Password password ->
({ model | password = password }, Cmd.none)
PasswordAgain password ->
({ model | passwordAgain = password }, Cmd.none)
Roll ->
(model, Random.generate NewFace (Random.int 1 100))
NewFace newFace ->
({ model | diceRoller = { dieFace = newFace} }, Cmd.none)
SearchImages ->
(model, getSearchResult model.termInput)
NewSearchResult (Ok newResult) ->
({ model | termResult = newResult }, Cmd.none)
NewSearchResult (Err _) ->
(model, Cmd.none)
ChangeTermInput term ->
({ model | termInput = term}, Cmd.none)
,我設法得到它多一點精緻,但是這並不編譯(見this Main.elm in the refactoring branch):
type DiceRollerMsg = Roll
| NewFace Int
type Msg = Change String
| Name String
| Password String
| PasswordAgain String
| MsgForDiceRoller DiceRollerMsg
| SearchImages
| NewSearchResult (Result Http.Error (List String))
| ChangeTermInput String
updateDiceRoller : DiceRollerMsg -> DiceRoller -> DiceRoller
updateDiceRoller msg model =
case msg of
Roll ->
model
NewFace newFace ->
{ model | dieFace = newFace}
updateDiceRollerCmd : Msg -> Cmd Msg
updateDiceRollerCmd msg =
case msg of
Roll ->
Random.generate NewFace (Random.int 1 100)
NewFace newFace ->
Cmd.none
updateCmd : Msg -> Model -> Cmd Msg
updateCmd msg model =
Cmd.batch
[ updateDiceRollerCmd msg
, getSearchResult model.termInput
]
updateModel : Msg -> Model -> Model
updateModel msg model =
case msg of
Change newContent ->
{ model | content = newContent }
Name name ->
{ model | name = name }
Password password ->
{ model | password = password }
PasswordAgain password ->
{ model | passwordAgain = password }
MsgForDiceRoller msg ->
{ model | diceRoller = updateDiceRoller msg model.diceRoller}
SearchImages ->
model
NewSearchResult (Ok newResult) ->
{ model | termResult = newResult }
NewSearchResult (Err _) ->
model
ChangeTermInput term ->
{ model | termInput = term}
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
(updateModel msg model, updateCmd msg model)
由於模式與DiceRollerMsg相匹配,但它試圖匹配消息,因此無法在updateDiceRoller中的Role中的類型不匹配的情況下進行編譯。如果我只是將輸入和返回類型更改爲DiceRollerMsg,我會得到:函數updateDiceRollerCmd
期望的參數是:DiceRollerMsg但它是:消息
另外,我不認爲updateCmd中的Cmd.batch是最佳解決方案。
我很感謝任何關於製作更好的Elm應用程序的意見,也包括這些問題之外。
哇,他們不是在開玩笑對榆樹社區的工作效率,非常感謝!我對這些映射器一無所知,並且絕對沒有想到可能需要在onclick中投射。 – mdworld