1

誰かがシグナルとエフェクトで私を助けてくれることを願っています。

私は Signals/Effects を調べており、-elm-architecture、特にexample 8を研究しています。

この例では(私が理解しているように)、形状をクリックすると:

  • 信号メッセージがアクションとともにアドレスに送信されます
  • SPINアクションは更新時に起動されます
  • シェイプが現在アニメーション化されていない場合、Tick も呼び出されます。

まったく同じフローを (同様のコードを使用して) 複製しようとしていますが、ボタンをクリックして HTML パッケージを使用する代わりに、スペースバーを使用して信号を送信したいだけです。

私のコードでは、スペースバーがシグナルをPunchアクションに送信します。例 8 と同じように、モデルで も呼び出しTickて更新したいと思いdebounceStateます。

私のコメントで、私が自分のPunchアクションに到達できることがわかりますが、Tick.

私はこの質問を見てきましたが、elm StartAppではなくKeyboard Signalを使用しているため、適用されないと思います。

Tick私の例で到達できない理由を誰かが説明できれば、とても感謝しています。

module Main (..) where

import Graphics.Element exposing (..)
import Time exposing (Time, second)
import Effects exposing (Effects)
import Keyboard


type alias DebounceState =
  Maybe
    { prevClockTime : Time
    , elapsedTime : Time
    }


type alias Model =
  { punching : Bool
  , count : Int
  , randomString: String
  , debounceState : DebounceState
  }


duration = second


-- MODEL


initialModel : ( Model, Effects Action )
initialModel =
  ( { punching = False
    , count = 0
    , randomString = ""
    , debounceState = Nothing
    }
  , Effects.none
  )


model : Signal ( Model, Effects Action )
model =
  Signal.foldp update initialModel (punch Keyboard.space)


-- ACTIONS


type Action
  = NoOp
  | Punch Bool
  | Tick Time


-- UPDATE


update : Action -> ( Model, Effects Action ) -> ( Model, Effects Action )
update action ( model, fx ) =
  case action of
    NoOp ->
      ( model, Effects.none )

    Punch isPunching ->
      case model.debounceState of
        Nothing ->
          ( { model |
              punching = isPunching
              , count = model.count + 1 }, Effects.tick Tick )

        Just _ ->
          ( { model |
              punching = isPunching
              , count = model.count + 2 }, Effects.none )

    -- I don't seem to reach `Tick` at all
    -- You'll notice that I try to apply a value to `randomString` in the
    -- conditional to indicate where I end up
    Tick clockTime ->
      let
        newElapsedTime =
          case model.debounceState of
            Nothing ->
              0

            Just {elapsedTime, prevClockTime} ->
              elapsedTime + (clockTime - prevClockTime)
      in
        if newElapsedTime > duration then
          ( {model | randomString = "foo"} , Effects.none )
        else
          ( {model | randomString = "bar"} , Effects.tick Tick )


-- SIGNAL


punch : Signal Bool -> Signal Action
punch input =
  Signal.map Punch input


-- VIEW

view : ( Model, Effects Action ) -> Element
view model =
  show model


main : Signal Element
main =
  Signal.map view model

それをTry Elmに直接貼り付けます。

4

1 に答える 1