首页 > 解决方案 > 类型不匹配 - 沙盒的第一个参数不是我所期望的

问题描述

我正在尝试添加订阅,因为我有一个下拉列表,这有助于确保当您在下拉列表之外单击时自动关闭。这样做时,我不得不改变model我的update.

链接(将带您到 Elm Bootstrap 站点)是我正在使用的下拉菜单,它使用的是 Bootstrap 4。

我得到的错误

第一个论点sandbox不是我所期望的:

295| Browser.sandbox 296|> { init = initialModel 297|>
, update = update 298|> , view = view 299|> }

这个参数是一个类型的记录:

{ init : ( Model, Cmd Msg )
, update : Msg -> Model -> ( Model, Cmd Msg )
, view : Model -> Html Msg
}

sandbox需要第一个论点是:

{ init : ( Model, Cmd Msg )
, update : Msg -> ( Model, Cmd Msg ) -> ( Model, Cmd Msg )
, view : ( Model, Cmd Msg ) -> Html Msg
}

别名模型

type alias Model =
    { currentNumber : Int, clicks : Int, outputList : List(String), uniqueValues : Dict Int Int, firstNumber : String, secondNumber : String, myDropState : Dropdown.State, items : List String, selectedItem : String, dictKeyToRemove : String,
    modalVisibility : Modal.Visibility  }

初始模型

initialModel : (Model, Cmd Msg)
initialModel =
    ({ currentNumber = 0, clicks = 0, outputList = [""], uniqueValues = Dict.empty, firstNumber = "", secondNumber = "", myDropState = Dropdown.initialState, items = ["Small", "Medium", "Large"], selectedItem = "Small", dictKeyToRemove = "",
    modalVisibility = Modal.hidden }, Cmd.none)

主要的

main : Program () Model Msg
main =
    Browser.sandbox
        { init = initialModel           
        , update = update      
        , view = view   
        }

订阅

subscriptions : Model -> Sub Msg
subscriptions model =
    Sub.batch
        [ Dropdown.subscriptions model.myDropState DropMsg ]

更新

update : Msg -> Model -> ( Model, Cmd Msg)
update msg model =
    case msg of   
        DropMsg state ->
            ({model | myDropState = state }, Cmd.none)

我不确定此时我缺少什么,我尝试改变论点但没有运气。

标签: typeerrorelmelm-architecture

解决方案


Browser.sandbox将创建一个简单且非常有限的程序。下拉列表需要除此之外的功能,即订阅,这意味着您需要使用其中一个Browser.elementBrowser.document代替。

的类型Browser.element是:

element :
    { init : flags -> ( model, Cmd msg )
    , view : model -> Html msg
    , update : msg -> model -> ( model, Cmd msg )
    , subscriptions : model -> Sub msg
    }
    -> Program flags model msg

相比Browser.sandbox

sandbox :
    { init : model
    , view : model -> Html msg
    , update : msg -> model -> model
    }
    -> Program () model msg

这里有三个不同之处:

  1. init接受一个参数,flags,它可以是任何东西,并将由运行时根据其类型进行解释。出于您的目的,仅使用()就足够了(本质上就是sandbox这样做的),但有关更多详细信息,请参阅指南的标志部分。

  2. initupdate返回( model, Cmd msg )而不仅仅是model. 这是您的错误的根本原因,因为您拥有updateinit函数( model, Cmd msg )element预期返回,但尝试将它们提供给sandbox. 这使编译器不高兴,因为它认为model应该是( Model, Cmd msg )而不是仅仅Model.

  3. element需要一个附加subscriptions功能,您已经定义但目前没有做任何事情,因为沙盒不接受它。

将所有这些放在一起,替换以下main函数应该适合您:

main : Program () Model Msg
main =
    Browser.element
        { init = \() -> initialModel           
        , update = update      
        , view = view
        , subscriptions = subscriptions  
        }

推荐阅读