2015-12-14 13 views
10

Sto imparando il funzionamento di Elm ma continuo a lottare con i segnali e le pressioni della tastiera. Il codice seguente è un esempio del pacchetto start-app. Mi piacerebbe averlo quando premo la barra spaziatrice che il contatore viene incrementato. Come si fa nell'esempio qui sotto?Come collegare la tastiera premere all'azione

import Html exposing (div, button, text) 
import Html.Events exposing (onClick) 
import StartApp.Simple as StartApp 


main = 
    StartApp.start { model = model, view = view, update = update } 


model = 0 


view address model = 
    div [] 
    [ button [ onClick address Decrement ] [ text "-" ] 
    , div [] [ text (toString model) ] 
    , button [ onClick address Increment ] [ text "+" ] 
    ] 


type Action = Increment | Decrement 


update action model = 
    case action of 
    Increment -> model + 1 
    Decrement -> model - 1 

risposta

9

Avrete bisogno di un uso regolare StartApp piuttosto che StartApp.Simple perché fornisce i mezzi per utilizzare gli effetti e le Attività.

Il Action necessita di un costruttore NoOp per consentire alla nostra vista di rimanere invariata quando un tasto non è la barra spaziatrice.

Quindi è necessaria una funzione che associ il valore Keyboard.presses a Action. Ecco il codice aggiornato:

import Html exposing (div, button, text) 
import Html.Events exposing (onClick) 
import StartApp 
import Effects exposing (Never) 
import Task 
import Keyboard 
import Char 

app = 
    StartApp.start 
    { init = init 
    , view = view 
    , update = update 
    , inputs = [ Signal.map spaceToInc Keyboard.presses ] 
    } 

main = 
    app.html 

type alias Model = Int 

init = 
    (0, Effects.none) 

view address model = 
    div [] 
    [ button [ onClick address Decrement ] [ text "-" ] 
    , div [] [ text (toString model) ] 
    , button [ onClick address Increment ] [ text "+" ] 
    ] 

type Action 
    = Increment 
    | Decrement 
    | NoOp 

update action model = 
    case action of 
    NoOp -> (model, Effects.none) 
    Increment -> (model + 1, Effects.none) 
    Decrement -> (model - 1, Effects.none) 

spaceToInc : Int -> Action 
spaceToInc keyCode = 
    case (Char.fromCode keyCode) of 
    ' ' -> Increment 
    _ -> NoOp 

port tasks : Signal (Task.Task Never()) 
port tasks = 
    app.tasks 
+0

Esattamente quello che stavo cercando, grazie. – Stanko

+0

Ho una domanda aggiuntiva. Come farei questo se volessi incrementare se premo due pulsanti contemporaneamente. Non riesco più a usare 'Keyboard.presses' perché non è possibile controllare se vengono premuti allo stesso tempo. – Stanko

+0

Dai un'occhiata a ['Keyboard.keysDown'] (http://package.elm-lang.org/packages/elm-lang/core/latest/Keyboard#keysDown). Quel segnale ti dà un 'Set' di tutti i tasti al momento. Potresti incorrere in problemi se stai cercando di determinare la pressione di un tasto piuttosto che un tasto tenuto continuamente premuto, ma dal momento che riceverai un nuovo segnale quando uno dei tasti è rilasciato, forse è quello che stai cercando. –