主信号中的多个信号,信号到文本
Multiple signals in main, signals to text
我刚接触 Elm,我遇到了一个问题,乍一看很简单,但我正在努力寻找解决问题的最佳实践。
练习:
编写一个程序,显示三个垂直排列的文本字段。第一个显示当前鼠标位置和 True 或 False,具体取决于鼠标左键当前是否按下。第二个文本框显示在第一个文本框下方,并根据 space 栏是否向下显示 True 或 False。最后,第三个文本字段显示 Keyboard.arrows 的当前值。试用生成的程序,以便了解所有这些输入信号的行为。
我的代码:
import Keyboard
import Mouse
import Html exposing ( Html )
main =
Signal.map mapStringToHtml position,
Signal.map mapStringToHtml mouseDown,
Signal.map mapStringToHtml spaceDown,
Signal.map mapStringToHtml arrows
mapStringToHtml : String -> Html
mapStringToHtml x = Html.text x
position : Signal String
position = Signal.map toString Mouse.position
mouseDown : Signal String
mouseDown = Signal.map toString Mouse.isDown
spaceDown : Signal String
spaceDown = Signal.map toString Keyboard.space
arrows : Signal String
arrows = Signal.map toString Keyboard.arrows
我的 main 没有编译,但我不知道我还需要怎么做。我在正确的道路上吗?能再短点吗?在这种情况下如何使用架构模型、视图、更新?
感谢任何帮助。
微创
你可以使用完整的 Elm 架构,但由于这似乎是一个学习练习,让我给你最小的改变来让它工作:
main =
Signal.map4 combineHtml
(Signal.map mapStringToHtml position)
(Signal.map mapStringToHtml mouseDown)
(Signal.map mapStringToHtml spaceDown)
(Signal.map mapStringToHtml arrows)
combineHtml pos mouse space arr =
Html.div [] [pos, mouse, space, arr]
mapStringToHtml : String -> Html
mapStringToHtml x = Html.div [] [Html.text x]
所以每段文字都有自己的div。 combineHtml
通过将它们放在另一个 div 中来组合所有这些。我认为这是快速将它们全部放在单独一行上的最简单方法。
要将 div 的 个信号 合并为一个,我们使用 Signal.map4
。它需要一个带有四个参数和四个信号的函数。每次其中一个信号更新时,都会使用信号的最新值评估函数。
重写
最小的更改对所有信息都一视同仁,并将它们全部放在单独的一行中。但问题包括鼠标位置和按钮应该在同一行上。所以这里是重写的程序,代码重复也少了一点:
import Keyboard
import Mouse
import Html exposing ( Html )
main = Signal.map4 view
Mouse.position
Mouse.isDown
Keyboard.space
Keyboard.arrows
view position mouseDown spaceDown arrows =
let
div = Html.div []
text = toString >> Html.text
spacer = Html.text " "
in
div
[ div [ text position, spacer, text mouseDown ]
, div [ text spaceDown ]
, div [ text arrows ]
]
let
-in
构造定义了一些局部常量。 div
是 Html.div
的快捷方式,其中第一个参数始终为空列表。 text
是一个函数,它首先应用 toString
,然后应用 Html.text
的结果。这些函数的长格式是:
div children = Html.div [] children
text something = Html.text (toString something)
-- or as pipeline: text something = something |> toString |> Html.text
我刚接触 Elm,我遇到了一个问题,乍一看很简单,但我正在努力寻找解决问题的最佳实践。
练习:
编写一个程序,显示三个垂直排列的文本字段。第一个显示当前鼠标位置和 True 或 False,具体取决于鼠标左键当前是否按下。第二个文本框显示在第一个文本框下方,并根据 space 栏是否向下显示 True 或 False。最后,第三个文本字段显示 Keyboard.arrows 的当前值。试用生成的程序,以便了解所有这些输入信号的行为。
我的代码:
import Keyboard
import Mouse
import Html exposing ( Html )
main =
Signal.map mapStringToHtml position,
Signal.map mapStringToHtml mouseDown,
Signal.map mapStringToHtml spaceDown,
Signal.map mapStringToHtml arrows
mapStringToHtml : String -> Html
mapStringToHtml x = Html.text x
position : Signal String
position = Signal.map toString Mouse.position
mouseDown : Signal String
mouseDown = Signal.map toString Mouse.isDown
spaceDown : Signal String
spaceDown = Signal.map toString Keyboard.space
arrows : Signal String
arrows = Signal.map toString Keyboard.arrows
我的 main 没有编译,但我不知道我还需要怎么做。我在正确的道路上吗?能再短点吗?在这种情况下如何使用架构模型、视图、更新?
感谢任何帮助。
微创
你可以使用完整的 Elm 架构,但由于这似乎是一个学习练习,让我给你最小的改变来让它工作:
main =
Signal.map4 combineHtml
(Signal.map mapStringToHtml position)
(Signal.map mapStringToHtml mouseDown)
(Signal.map mapStringToHtml spaceDown)
(Signal.map mapStringToHtml arrows)
combineHtml pos mouse space arr =
Html.div [] [pos, mouse, space, arr]
mapStringToHtml : String -> Html
mapStringToHtml x = Html.div [] [Html.text x]
所以每段文字都有自己的div。 combineHtml
通过将它们放在另一个 div 中来组合所有这些。我认为这是快速将它们全部放在单独一行上的最简单方法。
要将 div 的 个信号 合并为一个,我们使用 Signal.map4
。它需要一个带有四个参数和四个信号的函数。每次其中一个信号更新时,都会使用信号的最新值评估函数。
重写
最小的更改对所有信息都一视同仁,并将它们全部放在单独的一行中。但问题包括鼠标位置和按钮应该在同一行上。所以这里是重写的程序,代码重复也少了一点:
import Keyboard
import Mouse
import Html exposing ( Html )
main = Signal.map4 view
Mouse.position
Mouse.isDown
Keyboard.space
Keyboard.arrows
view position mouseDown spaceDown arrows =
let
div = Html.div []
text = toString >> Html.text
spacer = Html.text " "
in
div
[ div [ text position, spacer, text mouseDown ]
, div [ text spaceDown ]
, div [ text arrows ]
]
let
-in
构造定义了一些局部常量。 div
是 Html.div
的快捷方式,其中第一个参数始终为空列表。 text
是一个函数,它首先应用 toString
,然后应用 Html.text
的结果。这些函数的长格式是:
div children = Html.div [] children
text something = Html.text (toString something)
-- or as pipeline: text something = something |> toString |> Html.text