榆树:如何在浏览器中打印模型?

AIo*_*Ion 7 elm

这个问题有点傻,但我找不到直接的解决方案.

假设我有一个类似于此的模型: - 至少这个大.

initModel =
{ selectedCategory = "Vacantion"
, context = "root/Work"
, abstractSyntaxTree =
    [ { categoryName = "Work"
      , categoryContent =
            []
      }
    , { categoryName = "Vacation"
      , categoryContent =
            [ { folderName = "Hawaii"
              , folderContent =
                    FolderContent
                        ( [ { folderName = "Booking"
                            , folderContent = FolderContent ( [], [] )
                            }
                          ]
                        , [ "flightTicket.jpg" ]
                        )
              }
            ]
      }
    ]
}
Run Code Online (Sandbox Code Playgroud)

问题:如何在浏览器中显示它以使其看起来不错? - 没什么特别的 - 只是为了看看发生了什么就像一个快速的调试器..

到目前为止我尝试过的:

view = 
    div [] 
        [ pre [style [("width", "300") ] ] [ text (toString model)]
        ]
Run Code Online (Sandbox Code Playgroud)

在较小的模型上工作得很好,但在这种情况下,我得到这个长 - 单行 - 格式化json结构: 在此输入图像描述

我认为这就是问题:我在谷歌浏览器中安装的美化扩展程序不知道如何处理不包含\n在其中的字符串.为了检查这一点,我手动添加了一个\n- 并且该字符串在第二行被拆分,正如预期的那样.

输出形式text (toSting model)-这是一个字符串有没有\n在里面 -所以这就是为什么一切都显示在一行在浏览器-无论在宽度300像素的限制.

拆分字符串 - 通过\n我自己添加- 工作除了我不知道在哪里准确添加\n.要使其动态化,这需要模型的完整标记解析器.一种了解表达式开始的方法,下一个匹配括号的位置等等.我不够好构建这个解析器.我觉得我已经使这些东西变得复杂了.必须是更好的解决方案..

你们是怎么做到的?

win*_*elt 8

Elm不允许您枚举记录中的项目.对于类型安全毫无疑问.所以没有"干净"的方式来很好地显示记录.


更新:以下解决方案将不再适用于Elm 0.19.

它依赖于一个(已弃用的)函数toString,它可以将任何类型转换为字符串.自从Elm 0.17(当我这样做)以来,Elm已经在0.18中发布了一个很棒的调试器,它已经具有在单独窗口中跟踪模型和消息的功能.


对于调试,你可以做一些诡计,toString以便更整洁地打印它.下面是示例代码,您可以将其复制/粘贴到elm-lang.org/try.

只需将任何记录传递给该viewModel功能,它就会在浏览器中显示.这是非常粗糙的,可能不是很大的记录,但它会完成这项工作..

import Html exposing (Html, text, div, p, pre)
import Html.Attributes exposing (style)
import String

quote = "\""
indentChars = "[{("
outdentChars = "}])"
newLineChars = ","
uniqueHead = "##FORMAT##"
incr = 20


model = 
  { name = "Abe"
  , age = 49
  , someTuple = (18,49)
  , relatives = [ "Claire", "Bill" ]
  , comments = "any special characters like []{}, will not be parsed"
  , cars = [ { brand = "BMW", model = "535i" } ]
  }

viewModel : a -> Html msg
viewModel model =
  let
    lines =
      model
      |> toString
      |> formatString False 0 
      |> String.split uniqueHead
  in
    pre [] <| List.map viewLine lines

viewLine : String -> Html msg
viewLine lineStr =
  let
    (indent, lineTxt) = splitLine lineStr
  in
    p [ style 
        [ ("paddingLeft", px (indent))
        , ("marginTop", "0px")
        , ("marginBottom", "0px")
        ] 
      ]
      [ text lineTxt ]


px : Int -> String
px int =
  toString int
  ++ "px"

formatString : Bool -> Int -> String -> String
formatString isInQuotes indent str =
  case String.left 1 str of
    "" -> ""

    firstChar -> 
      if isInQuotes then
        if firstChar == quote then
          firstChar 
          ++ formatString (not isInQuotes) indent (String.dropLeft 1 str)
        else
          firstChar 
          ++ formatString isInQuotes indent (String.dropLeft 1 str)
      else
        if String.contains firstChar newLineChars then
          uniqueHead ++ pad indent ++ firstChar
          ++ formatString isInQuotes indent (String.dropLeft 1 str)
        else if String.contains firstChar indentChars then
          uniqueHead ++ pad (indent + incr) ++ firstChar
          ++ formatString isInQuotes (indent + incr) (String.dropLeft 1 str)
        else if String.contains firstChar outdentChars then
          firstChar ++ uniqueHead ++ pad (indent - incr)
          ++ formatString isInQuotes (indent - incr) (String.dropLeft 1 str)
        else if firstChar == quote then
          firstChar 
          ++ formatString (not isInQuotes) indent (String.dropLeft 1 str)
        else
          firstChar 
          ++ formatString isInQuotes indent (String.dropLeft 1 str)

pad : Int -> String
pad indent =
  String.padLeft 5 '0' <| toString indent

splitLine : String -> (Int, String)
splitLine line =
  let
    indent = 
      String.left 5 line
      |> String.toInt
      |> Result.withDefault 0
    newLine =
      String.dropLeft 5 line
  in
    (indent, newLine)

main =
  viewModel model
Run Code Online (Sandbox Code Playgroud)