【问题标题】:Refactoring update fuction in a basic Elm app在基本 Elm 应用程序中重构更新功能
【发布时间】:2017-06-13 17:38:01
【问题描述】:

我最近开始使用 Elm,但我遇到了更新功能的问题。我的目标是将我的大 Main.elm 文件拆分为多个较小的文件,但为此我首先尝试将主要组件拆分为同一文件中的较小组件。为此,我非常依赖this very informative guide

拆分 Model 和 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 上的类型不匹配导致编译失败,但它正在尝试匹配 Msg。如果我只是将输入和返回类型更改为 DiceRollerMsg,我会得到:函数 updateDiceRollerCmd 期望参数是:DiceRollerMsg 但它是:Msg

我也不认为 updateCmd 中的 Cmd.batch 是这里最好的解决方案。

感谢您为制作更好的 Elm 应用提供的任何意见,除了这些问题。

【问题讨论】:

    标签: elm


    【解决方案1】:

    您的编译错误源于使用Msg 作为updateDiceRollerCmd 的输入和返回值,而case 语句使用DiceRollerMsg。您可以通过从MsgForDiceRoller 进行模式匹配并映射到MsgForDiceRoller 来修复此功能。

    updateDiceRollerCmd : Msg -> Cmd Msg
    updateDiceRollerCmd msg =
        case msg of
            MsgForDiceRoller Roll ->
                Random.generate NewFace (Random.int 1 100)
                    |> Cmd.map MsgForDiceRoller
    
            _ ->
                Cmd.none
    

    您的视图中还有一个编译错误,您需要将onClick Roll 更改为onClick (MsgForDiceRoller Rool)

    【讨论】:

    • 哇,他们不是在开玩笑 Elm 社区的效率,谢谢!我对那些映射器一无所知,并且绝对没想到它会成为可能并且需要在 onclick 中进行投射。
    猜你喜欢
    • 2019-06-16
    • 2018-04-13
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    • 2020-12-24
    • 2015-06-13
    • 1970-01-01
    • 2012-09-21
    相关资源
    最近更新 更多