首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >转换Html DOM

转换Html DOM
EN

Stack Overflow用户
提问于 2016-08-05 19:08:53
回答 2查看 408关注 0票数 2

我是Elm的新手,到目前为止我真的很喜欢它,但我遇到了一个我似乎无法理解的问题。

例如,我有一个Html DOM

代码语言:javascript
运行
复制
div []
  [ h1 [] [text "Headline 1"]
  , p [] [text "Some text"]
  , h2 [] [text "Headline 2"]
  ]

我想在每个h1-6元素中添加a-link,这样就可以把它转换成像这样的东西(保持简单)

代码语言:javascript
运行
复制
div []
  [ h1 [] [ text "Headline 1"
          , [a [name "headline"] [text "#"]
          ]
  , p [] [text "Some text"]
  , h2 [] [text "Headline 2"
          , [a [name "headline"] [text "#"]
          ]
  ]

从概念上讲,这并不是很难。查看DOM,如果元素是h1-6,则添加一个a-link作为子元素。然而,我对Elm的理解还不够好,无法让它正常工作。

这是我到目前为止一直在尝试的。

代码语言:javascript
运行
复制
transform : Html a -> Html a
transform node =
    -- check if the tag is h1-h6
    case node.tag of
        -- add a-link to h1 children
        "h1" -> { node | children = (a [name "headline"] [text "#") :: node.children }
        "h2" -> { node | children = (a [name "headline"] [text "#") :: node.children }
        -- do this for all nodes in the tree
        _ -> { node | children = List.map transform node.children }

这不管用。

代码语言:javascript
运行
复制
The type annotation for `transform` does not match its definition.

40| transform : Html a -> Html a
                ^^^^^^^^^^^^^^^^
The type annotation is saying:

    VirtualDom.Node a -> VirtualDom.Node a

But I am inferring that the definition has this type:

    { b | tag : String, children : List (Html a) }
    -> { b | children : List (Html a), tag : String }

我知道我不能做node.tag,因为泛型类型a可能没有这个字段。它就不是类型安全的。例如,文本节点没有标记字段,但仍然是Html.Html a的实例。

代码语言:javascript
运行
复制
> text "Hello World"
{ type = "text", text = "Hello World" } : Html.Html a

我的问题是,我如何才能做到这一点?我能这么做吗?还是说我不应该这么做?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-05 19:42:40

无法修改Html msg类型的现有值。

它们是最终的内部结构,由Virtual DOM呈现给实际的HTML节点作为程序的输出。

Html msgVirtualDom.Node a的别名

您正试图将它们用作记录,但这只是一个JavaScript对象。

Elm REPL在这里输出抽象数据结构的字符串表示:

代码语言:javascript
运行
复制
> text "Hello World"
{ type = "text", text = "Hello World" } : Html.Html a -- not a record

与其尝试转换Html msg -> Html msg,不如尝试如下所示:

代码语言:javascript
运行
复制
-- Input example: [ "#", "http://google.com/", "http://package.elm-lang.org/" ]

linksView : List String -> Html msg
linksView links =
    links
        |> List.map (\link -> a [ href link ] [ text link ])
        |> div [] -- Expected output: <div> with thre links
票数 2
EN

Stack Overflow用户

发布于 2016-08-05 19:48:52

在Elm中,Html a实际上只用作输出。您永远不会以transform函数尝试的方式将其用作输入。

通过创建一个模型来描述您的域,然后将其传递给一个view函数来呈现html,您将获得更好的服务。

代码语言:javascript
运行
复制
type alias Article =
  { priority : Priority
  , headline : String
  , body : String
  }

type alias Model =
  List Article

type Priority = First | Second

然后,您的视图可能如下所示:

代码语言:javascript
运行
复制
view : Model -> Html msg
view =
  div [] << List.map viewArticle

viewArticle : Article -> Html msg
viewArticle article =
  let
    priorityTag =
      case article.priority of
        First -> h1
        Second -> h2
  in
    div []
      [ priorityTag []
        [ text article.headline
        , a [ name "headline" ] [ text "#" ]
        ]
      , p [] [ text article.body ]
      ]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38787764

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档