2015-11-15 78 views
1

我刚进入榆树,我被困在一见钟情的问题看起来很简单,但我正在努力寻找解决问题的最佳实践。主信号中的多个信号,信号到文本

演习:

编写一个程序,显示了三个文本字段,垂直排列。第一个显示当前的鼠标位置以及True或False,具体取决于鼠标左键是否当前关闭。第二个文本框显示在第一个下面,根据空格键是否关闭显示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 

我主不编译,但我不知道我需要怎么回事做到这一点。我在正确的道路上吗?它能缩短吗?如何在这种情况下使用体系结构模型,查看和更新​​?

任何帮助表示赞赏。

回答

4

微创

你可以去全榆木建筑,但因为这似乎是一个学习锻炼,让我给你的最小变化得到它的工作:

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结构定义了一些局部常量。 divHtml.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 
+0

谢谢你的伟大答案,但唯一缺少的是该位置必须在mouseDown旁边。我想实现我只需要改变combineHtml方法。 – Stanko

+0

对,我可以更新我的答案以包含该内容 – Apanatshka