drop-down-menu - 如何在 Elm lang 中使用选择(下拉)标签

标签 drop-down-menu html-select dropdown elm

我想使用以下代码在我的 elm 应用程序中呈现简单的下拉列表,但它没有按预期工作。我想保留联合类型 Role 并尽可能避免使用字符串。

在 Elm 中使用下拉菜单的最佳方式是什么?我还没有找到任何例子。

import Html exposing (..)
import Html.App exposing (beginnerProgram)
import Html.Events exposing (..)
import Html.Attributes exposing (..)
import Json.Decode

main =
  beginnerProgram
    { model = initialModel
    , view = view
    , update = update
    }

initialModel =
  { role = None
  }

type Role
  = None
  | Admin
  | User

type alias Model = 
  { role: Role
  }

type Msg
  = SelectRole Role


update msg model =
  case msg of
    SelectRole role ->
      { model | role = role }


view : Model -> Html Msg
view model =
  div
    []
    [ select
        [ ]
        [ viewOption None
        , viewOption Admin
        , viewOption User
        ]
    , pre [] [ text <| toString model ]
    ]



viewOption : Role -> Html Msg
viewOption role =
  option
    [ onClick (SelectRole role) ]
    [ text <| toString role ]

最佳答案

onClick处理程序实际上不适用于 option元素。相反,您需要捕获 change事件并查看 JSON targetValue看看选择了什么。

我会先删除 onClick处理程序,而是设置 option标签value属性:

viewOption : Role -> Html Msg
viewOption role =
  option
    [ value <| toString role ]
    [ text <| toString role ]

现在您需要一个 JSON 解码器,它可以接收事件的 targetValue字符串并将其转换为 Role :

targetValueRoleDecoder : Json.Decode.Decoder Role
targetValueRoleDecoder =
  targetValue `Json.Decode.andThen` \val ->
    case val of
      "Admin" -> Json.Decode.succeed Admin
      "User" -> Json.Decode.succeed User
      "None" -> Json.Decode.succeed None
      _ -> Json.Decode.fail ("Invalid Role: " ++ val)

现在您只需要将其添加到 select change事件处理程序:

    [ select
        [ on "change" (Json.Decode.map SelectRole targetValueRoleDecoder)
        ]
        [ viewOption None
        , viewOption Admin
        , viewOption User
        ]

我们不得不求助于字符串的事实仅仅是必须将值从 DOM 事件转换为有效联合类型的产物。您仍然希望保留 Role作为联合类型;您现在只需要创建针对每个联合类型的 JSON 解码器,因为 Elm(还)不支持任何类型的自动字符串到联合类型功能。

关于drop-down-menu - 如何在 Elm lang 中使用选择(下拉)标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39371105/

相关文章:

javascript - 在 jQuery 插件 dropdown.js 中添加更改事件的回调

mysql - 如何从 mysql 数据库创建雷达 Chartjs 的下拉列表?

PHP CodeIgniter - 使用 foreach 的下拉列表不显示 "selected"值

css - 在过滤选项时保持下拉 <select> 控件打开

html - 带有滚动条问题的多级下拉菜单

javascript - 从在 JSFiddle 上工作的数组填充下拉列表,但在本地计算机上不起作用?

java - Java 中的下拉式提示搜索

jquery - 如何使用外部选择框来过滤数据表?

javascript - ng-init 未在 ng-options 中设置第一个选择选项

javascript - 具有过滤功能的 HTML 和 javascript <select> 标签