Apanatshka 的回答 (andothers) 是有道理的,但作为 Elm 的初学者,我很难将解释应用于实际代码。经过一番折腾,这里是呈现自动更新日期所需的最少量代码(使用 Elm v0.16.0):
import Signal
import Html exposing (Html, text)
import Time exposing (Time, every)
import Date exposing (Date, Month, fromTime, year, month, day, hour, minute, second)
-- not used by foldp (https://stackoverflow.com/a/34095298/480608)
startTime = 0
type Action = Update Date
type alias Model = Date
showDate : Date -> String
showDate date = toString (month date) ++ " " ++
toString (day date) ++ ", " ++
toString (year date) ++ " " ++
toString (hour date) ++ ":" ++
toString (minute date) ++ ":" ++
toString (second date)
update : Action -> Model -> Model
update (Update date) _ = date
model : Signal Model
model =
Signal.foldp update (fromTime startTime) clock
timeToAction : Time -> Action
timeToAction time = Update <| fromTime time
clock : Signal Action
clock =
Signal.map timeToAction <| every Time.second
main : Signal Html
main =
Signal.map view model
view : Model -> Html
view model =
text <| showDate model
这是一个稍微复杂一点的例子,它将时钟合并到其他信号中。不知道这在多大程度上符合 elm 最佳实践,但它确实有效,而且它可以作为一个有用的学习工具,就像它对我所做的那样。
import Signal
import Html exposing (..)
import Html.Events exposing (..)
import Keyboard
import Char
import Time exposing (Time)
import Date exposing (Date, Month, fromTime, year, month, day, hour, minute, second)
startTime = 0
type Action =
NoOp
| Increment
| Decrement
| Update Time
type alias Model = {
count: Int,
time: Time
}
showDate : Date -> String
showDate date = toString (month date) ++ " " ++
toString (day date) ++ ", " ++
toString (year date) ++ " " ++
toString (hour date) ++ ":" ++
toString (minute date) ++ ":" ++
toString (second date)
actions : Signal.Mailbox Action
actions =
Signal.mailbox NoOp
update : Action -> Model -> Model
update action model =
case action of
NoOp -> model
Increment -> { model | count = model.count + 1 }
Decrement -> { model | count = model.count - 1 }
Update time -> { model | time = time }
model : Signal Model
model =
Signal.foldp update { count = 0, time = startTime } (Signal.mergeMany [
actions.signal,
keyPressesToAction,
clock
])
keyPressesToAction : Signal Action
keyPressesToAction =
let
keyCodeToAction keyCode =
case Char.fromCode keyCode of
'=' -> Increment
'-' -> Decrement
_ -> NoOp
in
Signal.map keyCodeToAction Keyboard.presses
timeToAction : Time -> Action
timeToAction time = Update time
clock : Signal Action
clock = Signal.map timeToAction (Time.every Time.second)
main : Signal Html
main =
Signal.map (view actions.address) model
view : Signal.Address Action -> Model -> Html
view address model =
div [] [
text <| showDate <| fromTime model.time,
div []
[ button [ onClick address Decrement ] [ text "-" ]
, text <| toString model.count
, button [ onClick address Increment ] [ text "+" ]
]
]