在Elm中使用动态数量的按钮 [英] Use a dynamic number of buttons with 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屋!