在Elm中使用动态数量的按钮 [英] Use a dynamic number of buttons with Elm

查看:73
本文介绍了在Elm中使用动态数量的按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一些按钮,按钮的数量会随着用户操作而变化(列表或数组中的每个值一个)。

I would like to create some buttons whose number will vary with user actions (one per value in a list or array)).

我能够创建按钮,但在 update 中不知道按下了哪个按钮。

I'm able to create the buttons but not to know in update which one was pressed.

例如,在下面的简化代码中,如何增加数据中与按下按钮相对应的值?

For instance, in the following reduced code, how can I increment the value in data corresponding to the pressed button?

module Main exposing (..)

import Html exposing (..)
import Html.Events exposing (..)
import Array exposing (..)

main =
    Html.program
        { init = init
        , view = view
        , update = update
        , subscriptions = subscriptions
        }

-- MODEL

type alias Model =
    { data : Array Int
    }

init : ( Model, Cmd Msg )
init =
    ( Model (fromList [ 11, 22, 33 ]), Cmd.none )

-- UPDATE

type Msg
    = Play  -- or Play Int ?


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        Play ->
            ( model, Cmd.none )

-- VIEW

view : Model -> Html Msg
view model =
    div [] (Array.map viewButton model.data |> toList)

viewButton : Int -> Html Msg
viewButton v =
    div [] [ button [ onClick Play ] [ text (toString v) ] ]

subscriptions : Model -> Sub Msg
subscriptions model =
    Sub.none


推荐答案

对于您对 Msg 的评论,您处于正确的轨道,也许拥有 Play Int 构造函数。我们通常在Elm中处理此问题的方法是携带索引。您可以在视图函数中使用 Array.indexedMap 来提取索引和数据。

You are on the right track with your comment about Msg maybe having a Play Int constructor. The way we usually handle this in Elm is by carrying around the index. You can use Array.indexedMap in the view function to pull both the index and data.

这里是代码相关部分的更新版本,仅做了一些更改,使单击时的每个按钮递增:

Here is an updated version of the relevant parts of your code with only a few changes that increments each button on click:

type alias Model =
    { data : Array Int
    }

-- UPDATE
type Msg
    = Play Int

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        Play idx ->
            ( { model | data = incrementAt idx model.data }, Cmd.none )

incrementAt : Int -> Array Int -> Array Int
incrementAt idx arr =
    let
        cur =
            Maybe.withDefault 0 (get idx arr)
    in
        set idx (cur + 1) arr

-- VIEW
view : Model -> Html Msg
view model =
    div [] (Array.indexedMap viewButton model.data |> toList)

viewButton : Int -> Int -> Html Msg
viewButton idx v =
    div [] [ button [ onClick (Play idx) ] [ text (toString v) ] ]

此代码段可在 runelm.io 上找到。

This snippet is available on runelm.io.

这篇关于在Elm中使用动态数量的按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆