如何在页面加载时过滤信号

How to filter a Signal on page load

为了学习,我尝试仅在单击按钮时加载内容。到目前为止,我已经设法:

但我的问题是 Ajax 调用在页面加载后仍然会被触发。

代码如下:

-- SIGNALS & MAILBOX

inbox : Signal.Mailbox String
inbox =
  Signal.mailbox "SOME TEXT"

result : Signal.Mailbox String
result =
  Signal.mailbox ""

--  VIEW

view : String -> Html
view msg  =
  div [] [
    h1 [] [text "Mailbox3"],
    p [] [text msg],
    button
      [onClick inbox.address "GETPERF"]
      [text "click perf"],
 ]

main : Signal Html
main =
  Signal.map view result.signal

-- TASK & EFFECTS

port fetchReadme : Signal (Task Http.Error ())
port fetchReadme =
  inbox.signal
    |> Signal.filter (\sig -> sig == "GETPERF" ) "boo"
    |> Signal.map (\_ -> Http.getString "http://localhost:3000/dates" `andThen` report)


report : String -> Task x ()
report html =
  Signal.send result.address html

有什么方法可以防止第一个 Ajax 调用页面加载? (或者做这一切的一些更惯用的方式?)

您收到初始 ajax 请求的原因是 Signal.filter 仍保持 "boo" 的初始值(请参阅 Signal.filter documentation here)。通过使用下划线参数,该值在下一个 Signal.map 语句中被忽略,但 Http 任务仍会返回,这就是为什么您在页面加载时看到初始 ajax 请求的原因。

您可以编写一个条件,只在 sig"GETPERF" 的正确情况下发送 ajax 请求,而不是使用 Signal.filter。如果 sig 不是 而不是 "GETPERF"(如在页面加载中),您实际上可以通过返回 Task.succeed () 不执行任何操作。这是一个经过以下更改的重构 fetchReadme 函数:

port fetchReadme : Signal (Task Http.Error ())
port fetchReadme =
  let
    fetchAndReport sig =
      if sig == "GETPERF" then
        Http.getString "http://localhost:3000/dates"
          `andThen` report
      else
        Task.succeed ()
  in
    Signal.map fetchAndReport inbox.signal