我想创建一些按钮,其数量会随用户操作而变化(列表或数组中每个值一个)。
我可以创建按钮但不知道在update
中按了哪个按钮。
例如,在下面的简化代码中,如何增加与按下的按钮对应的data
中的值?
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
答案 0 :(得分:3)
您对Msg
可能拥有Play Int
构造函数的评论走在正确的轨道上。我们通常在Elm处理这个问题的方法是携带索引。您可以使用Array.indexedMap
函数中的view
来提取索引和数据。
以下是代码相关部分的更新版本,只有一些更改会使点击时的每个按钮递增:
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上找到。