使用榆树和 select
Work with elm and select
我尝试通过自定义示例了解 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 创建我的事件?
更新:onInput
有效,请参阅下面的另一个答案,其中包含 0.19 工作代码:
是的,您将需要使用 on
来处理更改事件。如果您查看 source for other event handlers built into Elm, like onClick
,您会发现它们都是使用 on
函数构建的。
这是一个使用 targetValueIntParse from 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
供 Elm 新手(像我一样)将来参考:使用 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) ]
这是 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 }
使用 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
}
这适用于 Ellie on 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 }
我尝试通过自定义示例了解 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 创建我的事件?
更新:onInput
有效,请参阅下面的另一个答案,其中包含 0.19 工作代码:
是的,您将需要使用 on
来处理更改事件。如果您查看 source for other event handlers built into Elm, like onClick
,您会发现它们都是使用 on
函数构建的。
这是一个使用 targetValueIntParse from 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
供 Elm 新手(像我一样)将来参考:使用 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) ]
这是 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 }
使用 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
}
这适用于 Ellie on 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 }