Текущий год с 4 цифрами в вязе 0.19.1 - PullRequest
2 голосов
/ 16 апреля 2020

Как я могу сделать функцию, чтобы получить текущий год с 4 цифрами, используя ELM 0.19.1? Я прочитал что-то, но ничего не работает с 0.19.1.

Подпись:

getCurrentYear : Int

Выполнение:

getCurrentYear => 2020

Редактировать:

Возможно выполняется new Date().getFullYear() javascript код?

Ответы [ 2 ]

6 голосов
/ 17 апреля 2020

Самый простой способ - передать год с помощью flags при запуске приложения, поскольку текущий год вряд ли изменится в ходе работы приложения. В этом случае вы можете использовать предложенный вами фрагмент JavaScript ( ell ie пример ):

    Elm.Main.init({ 
      node: document.querySelector('main'), 
      flags: {
        year: new Date().getFullYear(),
      } 
    });
module Main exposing (main)

import Browser
import Html exposing (Html, p, text)


type alias Flags =
    { year : Int }


main : Program Flags Model Msg
main =
    Browser.element
        { init = \flags -> ( Model flags.year, Cmd.none )
        , view = view
        , update = update
        , subscriptions = \_ -> Sub.none
        }


type alias Model =
    { year : Int }


type Msg
    = NoOp


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        NoOp ->
            ( model, Cmd.none )


view : Model -> Html Msg
view model =
    p [] [ text "The year is ", text (String.fromInt model.year) ]

В качестве альтернативы вы можете использовать Time.now для запроса текущего времени, как подсказывает ответ Робина Зигмонда , однако это указывает на документацию Elm 0.18 (для elm-lang / core вместо elm / время ). Для 0.19 вам нужно и Time.Posix и Time.Zone, чтобы позвонить Time.toYear. Вы можете связать Time.now (Task, создающее значение Posix) и Time.here (Task, создающее Zone со смещением текущего часового пояса). ), чтобы получить эти значения в одном Cmd. Вот пример ( также на ell ie)

module Main exposing (main)

import Browser
import Html exposing (Html, p, text)
import Task exposing (Task)
import Time


type alias Flags =
    { year : Int }


main : Program () Model Msg
main =
    Browser.element
        { init = \() -> ( Model 0, whatYearIsIt |> Task.perform GotYear )
        , view = view
        , update = update
        , subscriptions = \_ -> Sub.none
        }


whatYearIsIt : Task x Int
whatYearIsIt =
    Task.map2 Time.toYear Time.here Time.now


type alias Model =
    { year : Int }


type Msg
    = GotYear Int


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        GotYear year ->
            ( { model | year = year }, Cmd.none )


view : Model -> Html Msg
view model =
    p [] [ text "The year is ", text (String.fromInt model.year) ]
6 голосов
/ 17 апреля 2020

Как я уже сказал в своем комментарии, в Elm невозможно определить функцию, которая возвращает текущий год. Вы должны получить такую ​​информацию из системы времени исполнения Elm (которая в основном JavaScript, но вам не нужно писать ее самостоятельно). Это происходит с помощью команд , где вы говорите системе времени выполнения что-то для вас. Но обратите внимание, что вы не можете просто получить «возвращаемое значение» этой команды и вернуть его в свой код Elm. Вместо этого вы должны передать его в функцию, которая может преобразовать его в «сообщение» (см. Базовое руководство по архитектуре Elm здесь , это важно понять, прежде чем вы сможете что-либо делать с Elm) - это затем позволяет вам сохранить значение в вашей модели и, таким образом, отобразить его в вашем приложении.

Эти шаблоны требуют некоторого осознания, особенно если вы не привыкли к чисто функциональному программированию - но как только вы получите Привыкли к этому, преимущества огромны, в том числе почти гарантированное отсутствие ошибок времени выполнения и значительно улучшенная способность рассуждать о вашем коде.

Для того, чтобы получить конкретный год, похоже, вам нужна эта библиотека , который дает вам (как now) Task, а не Cmd. Вы можете использовать Task.perform, чтобы преобразовать его в команду, которая задокументирована здесь - на самом деле это даже дает пример, который очень близко соответствует вашему варианту использования - я скопирую его здесь для потомков:

import Time  -- elm install elm/time
import Task

type Msg
  = Click
  | Search String
  | NewTime Time.Posix

getNewTime : Cmd Msg
getNewTime =
  Task.perform NewTime Time.now

Вам нужно будет заполнить это, чтобы соответствовать вашему собственному варианту использования, в частности вашему типу Msg. Но это дает хороший базовый план c. Чтобы узнать текущий год пользователя, вам нужно заменить тип Time.Posix на Int, а команду Time.now на (Task.map2 Time.toYear Time.here Time.now), как объяснил @bdukes в своем ответе.

...