如何将 purescript-halogen 组件渲染到 <head> 标签中
How to render purescript-halogen components into the <head> tag
如何将特定的 purescript-halogen 组件渲染到
标记中?
以下为 Halogen 1.0.0 编写的示例将样式表和段落呈现到 HTML 正文中:
module Main where
import Prelude
import Control.Monad.Eff (Eff)
import Data.Maybe (Maybe(Nothing))
import CSS as C
import Halogen as H
import Halogen.Aff as HA
import Halogen.HTML as HH
import Halogen.HTML.CSS as HS
import Halogen.Query.HalogenM as HQ
import Halogen.VDom.Driver as HV
styles :: forall p i. HH.HTML p i
styles = HS.stylesheet $
C.select C.body $ C.margin C.nil C.nil C.nil C.nil
content :: forall p i. HH.HTML p i
content = HH.p_ [ HH.text "Test" ]
main :: Eff (HA.HalogenEffects ()) Unit
main = HA.runHalogenAff $ HA.awaitBody >>= HV.runUI ui unit
where
ui = H.component { initialState : const unit
, render : const render
, eval : const $ HQ.halt "no query"
, receiver : const Nothing
}
render = HH.div_ [ styles, content ]
生成的DOM如下:
<html>
<head>
<title>Test</title>
<script async="" type="text/javascript" src="main.js"></script>
</head>
<body>
<div>
<style type="text/css">
body { margin: 0 0 0 0 }
</style>
<p>
Test
</p>
</div>
</body>
</html>
此示例有效,但根据 specification 样式元素仅允许 "where metadata content is expected",即
元素。所以我想在那里渲染样式表。我该如何实现?
注意 awaitBody
函数 - 在等待它加载的同时,这个 select 是 body
元素,在这种情况下这并不是您真正想要的。如果您想写入 head
,那么您将需要 select 并将其传递给 runUI
以获取呈现样式表的组件。
您还需要 运行 两个单独的组件,一个用于 head
,一个用于 body
:
module Main where
import Prelude
import Control.Monad.Aff.Console (CONSOLE)
import Control.Monad.Eff (Eff)
import Data.Const (Const)
import Data.Foldable (traverse_)
import Data.Maybe (Maybe(..))
import Data.Newtype (unwrap)
import Halogen as H
import Halogen.Aff as HA
import Halogen.HTML as HH
import Halogen.VDom.Driver (runUI)
bodyComponent :: forall m. H.Component HH.HTML (Const Void) Unit Void m
bodyComponent =
H.component
{ initialState: const unit
, render: const $ HH.div_ [ HH.text "A component" ]
, eval: absurd <<< unwrap
, receiver: const Nothing
}
styleComponent :: forall m. H.Component HH.HTML (Const Void) Unit Void m
styleComponent =
H.component
{ initialState: const unit
, render: const $ HH.style_ [ HH.text "body { background: #222; color: #eee }"]
, eval: absurd <<< unwrap
, receiver: const Nothing
}
main :: Eff (HA.HalogenEffects (console :: CONSOLE)) Unit
main = HA.runHalogenAff do
HA.awaitLoad
traverse_ (runUI styleComponent unit) =<< HA.selectElement "head"
traverse_ (runUI bodyComponent unit) =<< HA.selectElement "body"
如果他们需要通信,那么您可以使用 runUI
生成的 HalogenIO
记录中的 subscribe
和 driver
函数在他们之间建立通道。
我担心这样做,因为你应该通过一个空元素作为容器渲染的目标......但是当使用卤素提供的 VDom
驱动程序时它看起来至少表现得很好,因为 <head>
内容不会被样式组件替换(它附加到末尾)。不过,这基本上是未指定的行为,所以我不确定它是否一定适用于其他驱动程序。
如何将特定的 purescript-halogen 组件渲染到
标记中?以下为 Halogen 1.0.0 编写的示例将样式表和段落呈现到 HTML 正文中:
module Main where
import Prelude
import Control.Monad.Eff (Eff)
import Data.Maybe (Maybe(Nothing))
import CSS as C
import Halogen as H
import Halogen.Aff as HA
import Halogen.HTML as HH
import Halogen.HTML.CSS as HS
import Halogen.Query.HalogenM as HQ
import Halogen.VDom.Driver as HV
styles :: forall p i. HH.HTML p i
styles = HS.stylesheet $
C.select C.body $ C.margin C.nil C.nil C.nil C.nil
content :: forall p i. HH.HTML p i
content = HH.p_ [ HH.text "Test" ]
main :: Eff (HA.HalogenEffects ()) Unit
main = HA.runHalogenAff $ HA.awaitBody >>= HV.runUI ui unit
where
ui = H.component { initialState : const unit
, render : const render
, eval : const $ HQ.halt "no query"
, receiver : const Nothing
}
render = HH.div_ [ styles, content ]
生成的DOM如下:
<html>
<head>
<title>Test</title>
<script async="" type="text/javascript" src="main.js"></script>
</head>
<body>
<div>
<style type="text/css">
body { margin: 0 0 0 0 }
</style>
<p>
Test
</p>
</div>
</body>
</html>
此示例有效,但根据 specification 样式元素仅允许 "where metadata content is expected",即
元素。所以我想在那里渲染样式表。我该如何实现?注意 awaitBody
函数 - 在等待它加载的同时,这个 select 是 body
元素,在这种情况下这并不是您真正想要的。如果您想写入 head
,那么您将需要 select 并将其传递给 runUI
以获取呈现样式表的组件。
您还需要 运行 两个单独的组件,一个用于 head
,一个用于 body
:
module Main where
import Prelude
import Control.Monad.Aff.Console (CONSOLE)
import Control.Monad.Eff (Eff)
import Data.Const (Const)
import Data.Foldable (traverse_)
import Data.Maybe (Maybe(..))
import Data.Newtype (unwrap)
import Halogen as H
import Halogen.Aff as HA
import Halogen.HTML as HH
import Halogen.VDom.Driver (runUI)
bodyComponent :: forall m. H.Component HH.HTML (Const Void) Unit Void m
bodyComponent =
H.component
{ initialState: const unit
, render: const $ HH.div_ [ HH.text "A component" ]
, eval: absurd <<< unwrap
, receiver: const Nothing
}
styleComponent :: forall m. H.Component HH.HTML (Const Void) Unit Void m
styleComponent =
H.component
{ initialState: const unit
, render: const $ HH.style_ [ HH.text "body { background: #222; color: #eee }"]
, eval: absurd <<< unwrap
, receiver: const Nothing
}
main :: Eff (HA.HalogenEffects (console :: CONSOLE)) Unit
main = HA.runHalogenAff do
HA.awaitLoad
traverse_ (runUI styleComponent unit) =<< HA.selectElement "head"
traverse_ (runUI bodyComponent unit) =<< HA.selectElement "body"
如果他们需要通信,那么您可以使用 runUI
生成的 HalogenIO
记录中的 subscribe
和 driver
函数在他们之间建立通道。
我担心这样做,因为你应该通过一个空元素作为容器渲染的目标......但是当使用卤素提供的 VDom
驱动程序时它看起来至少表现得很好,因为 <head>
内容不会被样式组件替换(它附加到末尾)。不过,这基本上是未指定的行为,所以我不确定它是否一定适用于其他驱动程序。