我正在研究一个项目和我的队友,我正在讨论哪种方法更好。
在我看来,Html msg
似乎更通用,所以我认为我们应该尽可能地使用它,但我不能给他其他理由。
此外,我来自React和Redux,对我看起来像签名Html Msg
的组件就是我们所谓的Smart/Connected Components
和Html msg
就像{{1}我对这个假设是对的吗?
你能告诉我什么时候应该使用每一个吗?
谢谢
答案 0 :(得分:6)
将视图函数注释为返回Html msg
意味着您没有将视图绑定到特定的Msg
类型。因此,它更灵活,但它也限制了你可以做的事情。
在编写不呈现特定于Msg
特定代码的共享代码时,使用小写版本很有用。例如,您可以标准化一些布局代码:
pageTitle : String -> Html msg
pageTitle title =
h1 [ class "page-title" ] [ text title ]
上面的代码可以返回Html Msg
,但这会限制它分享它的能力,因为你将它绑定到特定的Msg
类型。
现在,如果您正在编写能够生成特定事件并将其绑定到Msg
构造函数的内容,那么您必须返回Html Msg
:
type Msg = RollDice | Rolled Int
diceButton : String -> Html Msg
diceButton label =
button [ class "fancy-btn", onClick RollDice ] [ text label ]
如果您尝试返回小写Html msg
,则无法编译上述定义。
如果我们停在那里,我可以看到这可能会如何与React中的智能与愚蠢的组件概念相似,因为看似小写的版本无法呈现会引发事件的Html,但这个类比并不是'真的抱着。假设您希望在系统范围内标准化按钮,但不希望将其与特定Msg
绑定。您可以通过接受点击时触发的Msg
参数来使函数更通用。
fancyButton : String -> msg -> Html msg
fancyButton label msg =
button [ class "fancy-btn", onClick msg ] [ text label ]
通常,如果您要编写要在内部或作为外部包共享的代码,则可以通过使用小型版Html msg
来提供更大的灵活性。这样做,您仍然可以编写可以触发事件的Html,就像在上面的fancyButton
示例中一样,它只是意味着您将一些责任传递给调用函数,而调用函数必须决定{{1}传入。
答案 1 :(得分:1)
msg
和Msg
确实是根本不同的种类。 m
/ M
是大写或小写的事实!
type Msg = RollDice | Rolled Int
正在定义新类型,该类型特定于您的计划。你可以随意调用它(只要用大写字母开头)。事实上,Msg
在这里真的是一个可怕的名字 - 这些消息是关于什么的?我不知道!
相反:type DiceMsg = RollDice | Rolled Int
。啊 - 现在我明白了,这是一个关于骰子的类型(消息)。得到它了! :)
也许你的程序也有:
type Suit = Spades | Hearts | Clubs | Diamonds
type CardMsg = DrawCard | CardDrawn Suit Int
然后你可以看到有什么区别:
Html DiceMsg
- 这是一些会产生关于骰子的消息。
Html CardMsg
- 这是一些会产生卡片消息的HTML。
现在让我们考虑像h1 [ class "page-title" ] [ text title ]
这样的html。 html的种是什么?
您可以看到它根本不会产生任何消息,因此将其称为Html DiceMsg
或 Html CardMsg
并不合理。但是,它可以用组成任何类型的HTML,对吗?您可以将Html DiceMsg
块上方的标题设置为{<1}},然后您将获得更大的 Html DiceMsg
块。
这就是Html msg
(小写m
)的含义:小写msg
表示“它可以是任何东西,让编译器弄明白”。编译器将根据您使用它的上下文决定msg
是DiceMsg
的占位符还是CardMsg
的占位符。 (用技术术语来说,msg
是类型变量。)
msg
为了获得最大的灵活性,您可以让函数的调用者控制他们希望您的代码生成哪种消息:
fancyButton : String -> msg -> Html msg
fancyButton label msg =
button [ class "fancy-btn", onClick msg ] [ text label ]
此处,msg
一个参数类型和返回类型。因此编译器可以发现fancyButton "draw a card" DrawCard
之类的调用会产生Html CardMsg
,而fancyButton "roll the dice" RollDice
会产生Html DiceMsg
。