如何在 Elm 中使用 StartApp 内部的端口
How to use ports inside StartApp in Elm
在我基于 StartApp 包的应用程序中,我有一个端口可以从内部与 JS 进行通信。目前我使用邮箱调用此端口
requestPalette :
{ address : Signal.Address String
, signal : Signal String
}
requestPalette = Signal.mailbox ""
requestPaletteFilter : Signal String
requestPaletteFilter =
Signal.filter (String.isEmpty >> not) "" requestPalette.signal
|> settledAfter (300 * Time.millisecond)
port request : Signal String
port request = requestPaletteFilter
并像这样使用它:
[on "input" targetValue (\str -> Signal.message requestPalette.address str)
我想知道是否有一种方法可以在 update
函数内部执行此操作,而不是从视图发送消息。
这适用于 elm 0.16(及之前),在 elm 0.17 订阅已更改为端口
为了从更新中向邮箱发送信号,您需要使用 StartApp
而不是 StartApp.Simple
,因为前者允许在 update
函数。
至少,您可能会有一个这样的操作,它定义了一个 No-Op 和一个用于发送字符串请求的操作:
type Action
= NoOp
| SendRequest String
您的 update
函数现在将包含类似于以下新 SendRequest 操作的情况。由于您使用的是处理 Effect 的 StartApp,因此您必须调用 Effects.task
,并且您映射到 Effect 的任务必须是 Action 类型,这就是为什么我们有 Task.succeed NoOp
return值。
update action model =
case action of
NoOp ->
(model, Effects.none)
SendRequest str ->
let
sendTask =
Signal.send requestPalette.address str
`Task.andThen` (\_ -> Task.succeed NoOp)
in
(model, sendTask |> Effects.task)
现在视图中的单击事件处理程序可以返回使用传递到视图中的 address
:
[ on "input" targetValue (Signal.message address << SendRequest) ]
我在 this gist 中有一个上述的工作示例。您只需订阅 javascript 中的 request
端口即可看到它的实际效果。
在我基于 StartApp 包的应用程序中,我有一个端口可以从内部与 JS 进行通信。目前我使用邮箱调用此端口
requestPalette :
{ address : Signal.Address String
, signal : Signal String
}
requestPalette = Signal.mailbox ""
requestPaletteFilter : Signal String
requestPaletteFilter =
Signal.filter (String.isEmpty >> not) "" requestPalette.signal
|> settledAfter (300 * Time.millisecond)
port request : Signal String
port request = requestPaletteFilter
并像这样使用它:
[on "input" targetValue (\str -> Signal.message requestPalette.address str)
我想知道是否有一种方法可以在 update
函数内部执行此操作,而不是从视图发送消息。
这适用于 elm 0.16(及之前),在 elm 0.17 订阅已更改为端口
为了从更新中向邮箱发送信号,您需要使用 StartApp
而不是 StartApp.Simple
,因为前者允许在 update
函数。
至少,您可能会有一个这样的操作,它定义了一个 No-Op 和一个用于发送字符串请求的操作:
type Action
= NoOp
| SendRequest String
您的 update
函数现在将包含类似于以下新 SendRequest 操作的情况。由于您使用的是处理 Effect 的 StartApp,因此您必须调用 Effects.task
,并且您映射到 Effect 的任务必须是 Action 类型,这就是为什么我们有 Task.succeed NoOp
return值。
update action model =
case action of
NoOp ->
(model, Effects.none)
SendRequest str ->
let
sendTask =
Signal.send requestPalette.address str
`Task.andThen` (\_ -> Task.succeed NoOp)
in
(model, sendTask |> Effects.task)
现在视图中的单击事件处理程序可以返回使用传递到视图中的 address
:
[ on "input" targetValue (Signal.message address << SendRequest) ]
我在 this gist 中有一个上述的工作示例。您只需订阅 javascript 中的 request
端口即可看到它的实际效果。