Подтвердить что ты не робот

Работайте с вязами и выберите

Я пытаюсь понять, как вис работает с пользовательским примером.

durationOption duration =
  option [value (toString duration) ] [ text (toString duration)]

view : Model -> Html Msg
view model =
  Html.div []
    [ h2 [] [ text "Month selector"]
    , select []
      (List.map durationOption [1..12])    
    ]

Это простой пример работы с выбором. Я бы хотел, каждый раз, когда я меняю значение месяца, оно умножается на значение, например, на 10. В соответствии с документацией нет событий типа onChange или onSelect, мне нужно создать мой с on?

4b9b3361

Ответ 1

ОБНОВЛЕНИЕ: onInput работает, см. Другой ответ ниже с рабочим кодом 0,19: fooobar.com/questions/456652/...

Да, вам нужно использовать on для обработки события изменения. Если вы посмотрите на источник для других обработчиков событий, встроенных в Elm, таких как onClick, вы увидите, что все они построены с использованием функции on.

Вот пример, который использует targetValueIntParse из elm-community/html-extra для преобразования строкового значения из опции в int.

Обновлено до Вяза-0,18

import Html exposing (..)
import Html.Events exposing (on)
import Html.Attributes exposing (..)
import Json.Decode as Json
import String
import Html.Events.Extra exposing (targetValueIntParse)


main =
    beginnerProgram { model = { duration = 1 }, view = view, update = update }


durationOption duration =
    option [ value (toString duration) ] [ text (toString duration) ]


view : Model -> Html Msg
view model =
    Html.div []
        [ h2 [] [ text "Month selector" ]
        , select [ on "change" (Json.map SetDuration targetValueIntParse) ]
            (List.map durationOption (List.range 1 12))
        , div [] [ text <| "Selected: " ++ (toString model.duration) ]
        ]


type Msg
    = SetDuration Int


type alias Model =
    { duration : Int }


update msg model =
    case msg of
        SetDuration val ->
            { model | duration = val }

Вы можете запустить этот пример в браузере https://runelm.io/c/ahz.

Ответ 2

Для использования в будущем для новичков в Elm (таких как я): с Elm 0.18.0 + elm-lang/html 2.0.0, событие onInput (см. Код ниже) работает. (Также обратите внимание на разницу в обозначении диапазона int (List.range 0 12 вместо [0..12]).

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onInput)


main =
  Html.beginnerProgram
    { model = model
    , view = view
    , update = update
    }



-- MODEL


type alias Model =
  { duration : Int
  }


model : Model
model =
  Model 0



-- UPDATE


type Msg
    = SetDuration String


update : Msg -> Model -> Model
update msg model =
  case msg of
    SetDuration s ->
      let result =
        String.toInt s
      in
        case result of
          Ok v ->
            { model | duration = v }

          Err message ->
            model


-- VIEW


view : Model -> Html Msg
view model =
  div []
    [ select [ onInput SetDuration ]
             (List.range 0 12 |> List.map intToOption)
    , div [] [ text <| "Selected: " ++ (toString model.duration) ]         
    ]


intToOption : Int -> Html Msg
intToOption v =
  option [ value (toString v) ] [ text (toString v) ]

Ответ 3

Вот обновление для Elm 0.19:

module Main exposing (main)

import Browser
import Html exposing (..)
import Html.Events exposing (on)
import Html.Attributes exposing (..)
import Json.Decode as Json
import String
import Html.Events.Extra exposing (targetValueIntParse)


main =
    Browser.sandbox { init = { duration = 1 }, view = view, update = update }


durationOption duration =
    option [ value (String.fromInt duration) ] [ text (String.fromInt duration) ]


view : Model -> Html Msg
view model =
    Html.div []
        [ h2 [] [ text "Month selector" ]
        , select [ on "change" (Json.map SetDuration targetValueIntParse) ]
            (List.map durationOption (List.range 1 12))
        , div [] [ text <| "Selected: " ++ (String.fromInt model.duration) ]
        ]


type Msg
    = SetDuration Int


type alias Model =
    { duration : Int }


update msg model =
    case msg of
        SetDuration val ->
            { model | duration = val }

Ответ 4

Пример с обработчиком onInput (вы также можете проверить Элли):

module Main exposing (main)

import Browser import Html exposing (Html, button, div, text, select, option) import Html.Attributes exposing (value, selected) import Html.Events exposing (onInput) import Dict exposing (Dict)

type alias Model =
    { options : Dict Int (String, Bool)
    }


initialModel : Model initialModel =
    { options = Dict.fromList [(0, ("All time", False)), (1, ("One week", True)), (2, ("24h", False))] 
    }


type Msg
    = Select String


update : Msg -> Model -> Model update msg model =
    case msg of
        Select value ->
            case String.toInt value of
                Just selectedID ->
                    let
                        changeSelection id (label, _) =
                            if id == selectedID then
                                (label, True)
                            else
                                (label, False)
                    in
                    {model | options = Dict.map changeSelection model.options}

                Nothing ->
                    model



view : Model -> Html Msg view model =
    let
        toOption (id, (label, isSelected)) =
            option [value (String.fromInt id), selected isSelected] [text label]
    in
    div []
        [ select [onInput Select] (List.map toOption <| Dict.toList model.options)
        , div [] [text "DEBUG"]
        , div [] [text <| Debug.toString model.options]
        ]


main : Program () Model Msg main =
    Browser.sandbox
        { init = initialModel
        , view = view
        , update = update
        }

Ответ 5

Это работает с Элли на Elm 0.19.0: https://ellie-app.com/58wGf2YsR9Ya1

Полный код:

import Browser
import Html exposing (..)
import Html.Events exposing (on)
import Html.Attributes exposing (..)
import Json.Decode as Json
import String
import Html.Events.Extra exposing (targetValueIntParse)

main =
    Browser.sandbox { init = init, view = view, update = update }

init =
    { duration = 1 }

durationOption duration =
    option [ value (String.fromInt duration) ] [ text (String.fromInt duration) ]


view : Model -> Html Msg
view model =
    Html.div []
        [ h2 [] [ text "Month selector" ]
        , select [ on "change" (Json.map SetDuration targetValueIntParse) ]
            (List.map durationOption (List.range 1 12))
        , div [] [ text <| "Selected: " ++ (String.fromInt model.duration) ]
        ]


type Msg
    = SetDuration Int


type alias Model =
    { duration : Int }


update msg model =
    case msg of
        SetDuration val ->
            { model | duration = val }