问题
I would like to create some buttons whose number will vary with user actions (one per value in a list or array)).
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
回答1:
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) ] ]
This snippet is available on runelm.io.
来源:https://stackoverflow.com/questions/41641476/use-a-dynamic-number-of-buttons-with-elm