我尝试了解elm如何使用自定义示例。
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])
]
使用select是一个简单的例子。我想,每次我更改月份值时,它会乘以值10,例如。根据文档,没有onChange
或onSelect
等事件,我是否必须使用on创建我的?
答案 0 :(得分:33)
以供Elm-newbies(像我一样)参考:使用Elm 0.18.0 + elm-lang / html 2.0.0,onInput
事件(见下面的代码)works。 (另请注意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) ]
答案 1 :(得分:23)
更新:onInput
有效,请参阅下面的另一个答案,其中包含0.19个有效代码:https://stackoverflow.com/a/41516493/540810
是的,您需要使用on
来处理更改事件。如果您查看内置于Elm中的source for other event handlers,例如onClick
,您会看到它们都是使用on
函数构建的。
以下是使用targetValueIntParse中的elm-community/html-extra将字符串值从选项转换为int的示例。
更新为Elm-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 :(得分:1)
这是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 }
答案 3 :(得分:0)
带有onInput
处理程序的示例(您也可以检查Ellie):
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
}
答案 4 :(得分:0)
这与Elm 0.19.0上的Ellie配合使用: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 }