Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elm 将多个复杂的父操作传递给深度嵌套的子视图_Elm - Fatal编程技术网

Elm 将多个复杂的父操作传递给深度嵌套的子视图

Elm 将多个复杂的父操作传递给深度嵌套的子视图,elm,Elm,免责声明:写完后,我意识到这可能是一个愚蠢的问题。请不要花太多时间阅读它。我对Elm、函数式编程非常陌生,不是UI爱好者 我在Elm中有一个视图,它返回Html Msg,并接受模型。以简单增量演示为例,我有以下典型设置: module Main exposing (..) import Browser import Html exposing (Html, button, div, text) import Html.Events exposing (onClick) -- MAIN main

免责声明:写完后,我意识到这可能是一个愚蠢的问题。请不要花太多时间阅读它。我对Elm、函数式编程非常陌生,不是UI爱好者

我在Elm中有一个视图,它返回
Html Msg
,并接受
模型
。以简单增量演示为例,我有以下典型设置:

module Main exposing (..)
import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)
-- MAIN

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

-- MODEL
type alias Model = Int

init : Model
init =
  0

-- UPDATE
type Msg
  = Increment
  | Decrement

update : Msg -> Model -> Model
update msg model =
  case msg of
    Increment ->
      model + 1

    Decrement ->
      model - 1

-- VIEW

view : Model -> Html Msg
view model =
  div []
    [ button [ onClick Decrement ] [ text "-" ]
    , div [] [ text (String.fromInt model) ]
    , button [ onClick Increment ] [ text "+" ]
    ]
我有一个非常复杂的按钮组件,我想将其提取到一个单独的函数中。我可以用普通的Html来做这件事

-- VIEW
some_html : Html msg
some_html =
  text "FOO"

view : Model -> Html Msg
view model =
  div []
    [ button [ onClick Decrement ] [ text "-" ]
    , div [] [ text (String.fromInt model) ]
    , button [ onClick Increment ] [ text "+" ]
    , some_html
    ]
我还可以传递我定义的
Msg
类型,并让“子函数”调用操作:

-- VIEW
make_button : Msg -> Html Msg
make_button msg =
  button [ onClick msg ] [ text "-" ]

view : Model -> Html Msg
view model =
  div []
    [ make_button Decrement
    , div [] [ text (String.fromInt model) ]
    , button [ onClick Increment ] [ text "+" ]
    ]
我的问题是:

我希望我的
make_按钮
功能能够处理多个操作。我发现有效的一种方法是传递所有可能的操作,然后传递一个键,即

-- VIEW
make_button : Msg -> Msg -> String -> Html Msg
make_button decr incr which =
  if which == "Decrement" then
  button [ onClick decr ] [ text "-" ]
  else button [ onClick incr ] [ text "+" ]

view : Model -> Html Msg
view model =
  div []
    [ make_button Decrement Increment "Decrement"
    , div [] [ text (String.fromInt model) ]
    , make_button Decrement Increment "Increment" -- doesn't matter here.
    ]
但是当操作的数量很大时(在我的用例中,我有20个左右的操作),这就变得很麻烦了

我应该创建一个分类词典吗?有没有办法做到这一点?这是件坏事吗?请给我悲伤。

我想象的场景是,许多嵌套的子组件可能希望能够动态调用父组件的任何操作,而不需要硬编码,这就是为什么我决定仍然问这个问题


谢谢。

你肯定想得太多了!你这样做的方式是

-- camel case is the convention in Elm ;)
makeButton : Msg -> Html Msg
makeButton msg =
    button
        [ onClick msg ]
        [ text <|
            -- an if statement would also work in this case
            case msg of
                Increment ->
                    "+"

                Decrement ->
                    "-"
        ]


view : Model -> Html Msg
view model =
    div []
        [ makeButton Decrement
        , div [] [ text (String.fromInt model) ]
        , makeButton Increment
        ]
——驼峰案是Elm的惯例;)
makeButton:Msg->Html Msg
马克巴顿味精=
按钮
[点击味精]
[正文]
"+"
减量->
"-"
]
查看:模型->Html消息
视图模型=
分区[]
[makeButton减量
,div[][text(String.fromInt模型)]
,makeButton增量
]

我认为你为自己挖的坑源于:“……可能希望有能力调用任何操作…”这通常意味着你在过度设计一些东西。你可能会发现以下演示对于理解Elm的重构哲学很有用:我要指出的一点是:
Msg
s是全局范围的。使用它们不需要将它们作为参数传入。