首页 > 解决方案 > 如何在 Elm 中使用可变数量的 UI 元素构造消息和更新函数?

问题描述

问候 StackOverflow!

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

模型和视图很简单:视图只是Array String在某处有一个字段。

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

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

消息可能是这样的:

type Msg = InputFieldUpdated Int String

这里,Int 是指要更新的字符串在 Array 中的位置。但是,如果我这样做,我可以通过将 Int 设置为超出范围的内容来创建引用不存在的数组位置的消息。

对于固定数量的输入元素,可以通过简单地为每个输入使用具有不同值的联合类型来非常优雅地解决这个问题,但是我的情况呢?在“使不可能的状态成为不可能”的领域中,我是否缺少一些技巧?

标签: elmelm-architecture

解决方案


但是,如果我这样做,我可以通过将 Int 设置为超出范围的内容来创建引用不存在的数组位置的消息。

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

请看一下这个ellie-app 示例。它主要是对您所描述的问题进行建模。渲染元素数组并且可以动态添加元素:

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

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

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

        Nothing ->
            model

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


推荐阅读