iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0

大家好。今天來讀一下 Halogen Guide 的第一章:Rendering Halogen HTML

在寫 halogen 的 component 前,需要先學習怎麼在 halogen 裡面寫 HTML。Tutorial 給了個簡單的例子:

import Halogen.HTML as HH

element = HH.h1 [ ] [ HH.text "Hello, world" ]

可以看出 halogen 寫 HTML 的方法是透過呼叫 function 去 render DOM tree,有點像沒有 jsx 的 React。Element 一律接收兩個 parameters:

  1. Array of HTML attrs, event handlers 或其他東西。似乎是所有不是 DOM children 的東西都會放這裡。
  2. Array of children.

因為 purescript 本身就是 declarative 的 language,所以即使 halogen 沒有另外使用別的 template language 去寫 HTML,寫出來的 halogen HTML 本身就已經很像 template。

接下來它有一段把普通 HTML 寫成 halogen HTML 的練習,這裡沒有什麼特別的我就不詳述了。

我個人比較在意的是,現階段我們沒有方法去把寫出來的 halogen HTML render 在網頁上,因為 mainrunUI 只能接收 Component 而不是 HTML。我寫了些 boilerplate 去做這件事,大家有興趣的話可以根據這個 diff 修改 src/Main.purs

@@ -2,12 +2,29 @@ module Main where
 
 import Prelude
 
-import App.Button as Button
+-- import App.Button as Button
 import Effect (Effect)
+import Halogen as H
 import Halogen.Aff as HA
+import Halogen.HTML as HH
 import Halogen.VDom.Driver (runUI)
 
 main :: Effect Unit
 main = HA.runHalogenAff do
   body <- HA.awaitBody
-  runUI Button.component unit body
+  -- runUI Button.component unit body
+  runUI component unit body
+
+component :: forall q i o m. H.Component q i o m
+component =
+  H.mkComponent
+    { initialState: \_ -> unit
+    , render
+    , eval: H.mkEval H.defaultEval
+    }
+
+render :: forall a cs m. Unit -> H.ComponentHTML a cs m
+render _ = element
+
+element :: forall w i. HH.HTML w i
+element = HH.h1 [ ] [ HH.text "Hello, world" ]

當然大家也可以直接改 /src/Button.purs

接下來提到 halogen HTML 是 typesafe 的,簡單點說就是你無法寫出 invalid 的 halogen HTML,因為不同 HTML element 的限制,像是可不可以有 children、有哪些 attributes 什麼的,是有包括在每個 element 的 type definition 裡的。寫出不存在的東西的話會導致 compilation error。

當然這麼嚴格的限制一定會有可以 override 的點(不然我們想用某個 element 的 attribute 但 halogen 不支援就完)。所以接下來就介紹了 IProp 和加上 custom HTML properties 的方法。

這樣大槪就看完了⋯!明天終於要真的開始學習 Component 了。


上一篇
[Day 6] 開始準備學習 purescript-halogen (~= 尚未開始學習)
下一篇
[Day 8] 基本 halogen component 拆解
系列文
從零開始的 Purescript8
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言