2017-01-13 14 views
0

我想創建一些按鈕,其數量將隨用戶操作(列表或數組中的每個值一個)而變化)。使用動態數量的按鈕與Elm

我能夠創建按鈕,但不知道在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 

回答

2

你在正確的軌道與您的評論有關Msg也許有一個Play Int構造上。我們通常在榆樹中處理這個問題的方式是通過實施指數。您可以在view函數中使用Array.indexedMap來提取索引和數據。

這裏是你的代碼的相關部分的更新版本,只有少數的變化是遞增的點擊每個按鈕:

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