【问题标题】:How to propagate clicks signal to model update in Elm?如何将点击信号传播到 Elm 中的模型更新?
【发布时间】:2014-01-27 21:11:08
【问题描述】:

我正在用 Elm 编写一个游戏,在这个游戏中有一个按钮,当按下该按钮时,应该将游戏板重置为其初始状态。但是,我不明白如何将按钮单击信号传播到板模型的更新功能。在下面的代码中,我刚刚将单位值传递给stepBoard,但我不能用它做很多事情,那么我该如何解决呢?

--MODEL
type Board = [(Int,Int)]
type Game = {name: String, board: Board}
defaultGame = {name = "Test", board = [(3,3)]}

--UPDATE
stepBoard click (colsInit, rowsInit) (rows, cols) g = 
          {g | board <- if ? then --some initial value (colsInit, rowsInit)
                        else      --some updated value using (rows, cols)} 
stepGame: Input -> Game -> Game                                      
stepGame {click, name, rowsColsInit, rowsCols} g = stepBoard click (0,0) (0,0) g
game = foldp stepGame defaultGame input

--INPUT
type Input = {click:(), name: String, rowsColsInit: (Int,Int), rowsCols: (Int,Int)}
input = Input <~ clicks ~ nameSignal ~ rowsColsInitSignal ~ rowsColsSignal

--VIEW
(btn, clicks) = Input.button "Click"

【问题讨论】:

    标签: elm elm-signal


    【解决方案1】:

    结合foldp 和点击信息可能不直观。

    通常采用的解决方案是使用 ADT 对不同的可能事件进行编码:

    data Input = Init (Int, Int)
               | Update { name         : String
                        , rowsCols     : ( Int, Int )
                        }
    input = merge (Init <~ (sampleOn clicks rowsColsInitSignal))
                  (OtherInput <~ nameSignal ~ rowsColsSignal)
    

    merge 合并两个信号,always 创建一个常量函数。

    现在您可以在更新函数中按大小写进行匹配:

    stepBoard input g = 
      let newBoard = 
            case input of
              Init (initRows, initCols) -> -- do your initialisation here
              Update {name, rowsCols}   -> -- do your update here
      in { g | board <- newBoard }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多