榆树当前日期

时间:2015-12-04 13:43:17

标签: date elm

在elm中,我有一个包含currentDate的模型,它是表示日期的字符串。我用信号更新它:

Signal.map (SetCurrentDate << timeToDateString) (Time.every Time.second)

SetCurrentDate是一项更新模型的动作(SetCurrentDate date -> { model | currentDate <- date}),timeToDateString从时间转换为字符串,如&#34; yyyy-mm-dd&#34;。< / p>

然而,这有两个问题:

  • model.currentDate仅在一秒钟后正确设置。因此,应用程序启动时的第二个是currentDate没有正确设置。
  • model.currentDate每秒设置一次,即使它每天都在变化。

有没有办法解决这个问题?那么currentDate是在应用程序的开头设置的(没有一秒延迟),而且它只是每天更新一次?

额外发现:

如果我将信号更改为Signal.dropRepeats <| Signal.map (SetCurrentDate << timeToDateString) (Time.every Time.second)(因此我删除重复),信号仅在日期更改时触发,而不是在应用程序启动时触发一次。

编辑:如果有更好的方法来了解Elm应用程序中的currentDate,我很乐意听到它。我的谷歌搜索什么都没有。

谢谢!

2 个答案:

答案 0 :(得分:4)

使用信号

您使用的是StartApp还是拥有自己的foldp?如果您使用的是StartApp,则最好查找start函数的代码并对其进行内联,以便您可以访问foldp

Signal.foldp对信号的初始值没有任何作用。因此,如果您使用Time.every second信号,则只会在一秒钟之后获得更新,并且仅在一天之后才会使用日期转换Signal.dropRepeats。您可以使用第三方Signal.Extra.foldp'库*中的signal-extra来解决此问题。它需要一个函数来从输入的初始值创建foldp的初始状态。

*完全披露:我是图书馆的作者

使用任务

task-tutorial库中有一项非常有用的任务,名为getCurrentTime。我认为这可以满足您的需求,而不需要每秒更新的信号。与Task.sleep一起,你可能会得到一些只能每天检查一次或两次的东西。

答案 1 :(得分:1)

Apanatshka的回答(and others)是有道理的,但作为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

这是一个稍微复杂的例子,它将时钟合并到其他信号中。不知道这符合榆树最佳实践的效果,但它有效,它可以作为一种有用的学习工具,就像它对我一样。

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 "+" ]
      ]
  ]