Elm,如何获取当前时间并将其 post 发送到服务器

Elm, how to get current time and post it to server

根据 and its helpful Ellie,我现在知道了我们如何在 Elm 0.18 中获取当前时间。

我想获取当前时间,然后 post 将其 JSON 发送到我的服务器。我已经有一个使用硬编码时间戳的 POST,但我只是不知道如何获取当前时间,然后将其包含在 JSON 我正在 POSTing.

我的猜测是我需要链接几个命令(获取当前时间,向服务器发送 POST)。

[我还阅读了 ,它展示了如何通过直接调用 update 函数来连续 运行 几个命令,这听起来是个不错的主意,但我我不确定这是否是我所需要的。]

实验([编辑]可能比预期的更分散注意力)

为了解决这个问题,我想我会尝试解决一个我可以在 Ellie 中更轻松地设置的类似问题。

the original Ellie中获取当前时间,更新到模型中,然后视图函数显示。

my version 中,我希望这是一个两步过程,因此将模型发展为当时的 Maybe FloatString 消息。 view 函数显示消息字符串和一个按钮——计划是当按下按钮时它告诉 运行 时间到 'go get the current time and then copy it across into the message slot'。

如果我能解决这个问题,我觉得我能解决我原来的问题。

我的艾莉还没有这样做。当你按下按钮时,时间被获取并放入 model 中的 time 槽中,但我不知道如何告诉 运行time 到 '...现在复制那个时候穿越到消息槽'。 PutTimeInMessage 消息已到位,但我不知道如何在 GetCurrentTime message/command.

之后将其发送到 运行

有什么建议吗?

这是我到目前为止的代码(编译),你可以 run here in Ellie:

module Main exposing (..)

import Html exposing (..)
import Html.Events exposing (..)
import Time exposing (Time)
import Date
import Task


type alias Model =
    { time : Maybe Float
    , message : String
    }


type Msg
    = OnTime Time
    | GetCurrentTime
    | PutTimeInMessage


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        OnTime t ->
            ( { model | time = Just t }, Cmd.none )

        GetCurrentTime ->
            ( model, getTime )

        PutTimeInMessage ->
            case model.time of
                Nothing ->
                    ( model, Cmd.none )

                Just t ->
                    ( { model | message = toString t }, Cmd.none )


view : Model -> Html Msg
view model =
    div []
        [ div []
            [ button [ onClick GetCurrentTime ] [ Html.text "Get now time." ]
            ]
        , model.message |> Html.text
        ]


getTime : Cmd Msg
getTime =
    Time.now
        |> Task.perform OnTime


main =
    Html.program
        { init = ( Model Nothing "Empty message.", Cmd.none )
        , update = update
        , view = view
        , subscriptions = always Sub.none
        }

在我看来,当收到 OnTime 消息时,您只需更新 message 字段和 time 字段即可。因此,整个 update 函数将如下所示:

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        OnTime t ->
            ( { model | time = Just t, message = toString t }, Cmd.none )

        GetCurrentTime ->
            ( model, getTime )

message设置在OnTime动作中,因为在GetCurrentTime时间是未知的,只有在getTime函数执行后才知道OnTime 收到消息。

如果您仍想使用单独的操作来放置 message,则可以选择以下代码:

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        OnTime t ->
            update PutTimeInMessage { model | time = Just t }

        GetCurrentTime ->
            ( model, getTime )

        PutTimeInMessage ->
            case model.time of
                Nothing ->
                    ( model, Cmd.none )

                Just t ->
                    ( { model | message = toString t }, Cmd.none )

但老实说,最好的解决方案是在视图中以不同的方式显示 time,因此您不需要 message 字段(但我可能不需要查看全图):

view : Model -> Html Msg
view model =
    div []
        [ div []
            [ button [ onClick GetCurrentTime ] [ Html.text "Get now time." ]
            ]
        , viewTime model.time
    ]

viewTime : Maybe Float -> Html Msg
viewTime time =
  case time of
    Nothing -> Html.text "Empty message."
    Just t -> Html.text (toString t)

我遇到了 。因为我可以看到 Time.now 的类型是 Task 我想如果我使用 Http.toTask.

我可以根据我的目的调整这个例子

下面是我想出的解决方案 here it is in Ellie:

module Main exposing (..)

import Html exposing (..)
import Html.Events exposing (..)
import Http
import Json.Decode as JD
import Json.Encode as JE
import Task
import Time


type alias Model =
    { url : String
    }


type Msg
    = PostTimeToServer
    | PostDone (Result Http.Error String)


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        PostTimeToServer ->
            ( model, postTimeToServer model.url )

        PostDone _ ->
            ( model, Cmd.none )


view : Model -> Html Msg
view model =
    div []
        [ div []
            [ button [ onClick PostTimeToServer ] [ Html.text "POST the current time." ]
            ]
        ]


postTimeToServer : String -> Cmd Msg
postTimeToServer url =
    let
        getTime =
            Time.now

        postTime t =
            JD.string
                |> Http.post url (JE.float t |> Http.jsonBody)
                |> Http.toTask

        request =
            getTime                                            <<-- Here is
                |> Task.andThen postTime                       <<-- the key bit.
    in
        Task.attempt PostDone request


main =
    Html.program
        { init = ( Model "url_here", Cmd.none )
        , update = update
        , view = view
        , subscriptions = always Sub.none
        }