如何在Elm中使用可变数量的UI元素构造消息和更新功能?

时间:2018-08-31 11:04:44

标签: elm elm-architecture

问候StackOverflow!

假设我有一个Elm应用程序,该应用程序具有可变数量的文本输入字段。我想在模型中反映这些输入字段的状态。

模型和视图非常简单:视图只是在某个地方有一个Array String字段。

然后只需在该字符串列表上调用List.map (HTML input ...)即可计算视图。

但是,我有点不知道如何执行更新功能和消息类型。

消息可能像这样:

type Msg = InputFieldUpdated Int String

此处,Int引用要更新的字符串在Array中的位置。但是,如果以这种方式进行操作,则只需将Int设置为超出范围的内容,就可以创建引用不存在的数组位置的消息。

对于固定数量的输入元素,只需为每个输入使用具有不同值的并集类型,就可以非常优雅地解决此问题,但是我的情况呢?在“使不可能的状态变为不可能”领域,我是否缺少一些技巧?

1 个答案:

答案 0 :(得分:2)

  

但是,如果以这种方式进行操作,则只需将Int设置为超出范围的内容,就可以创建引用不存在的数组位置的消息。

根据Array.set的文档,如果索引超出范围,则阵列保持不变。

请查看此ellie-app example。它主要为您描述的问题建模。呈现元素数组,并且可以动态添加元素:

view : Model -> Html Msg
view model =
    div []
        [ div [] (toList (Array.indexedMap viewElement model.elements))
        , button [ onClick Add ] [ text "Add" ]
        ]

为了更新特定元素,您需要按索引获取它。由于Array.get的结果类型为Maybe a,因此类型系统将强制您处理所有情况(当元素存在且不存在时):

Increment index ->
    case get index model.elements of
        Just element ->
            { model | elements = set index (element + 1) model.elements }

        Nothing ->
            model

该示例仅用于演示目的,如果不需要当前元素,则可以安全使用Array.set函数。