【问题标题】:How to do document.createElement in ReScript如何在 ReScript 中执行 document.createElement
【发布时间】:2021-05-25 13:45:55
【问题描述】:

ReScript 似乎是编写 JS 代码的更好方法,但我无法找到应该是简单的单行文档的内容。

如何调用document.createElement() 之类的函数?

我通过查看此页面尝试了 Js.document、Dom.document:https://rescript-lang.org/docs/manual/latest/api,但该代码在操场上出现错误:

在Js中找不到document的值
在 Dom 中找不到值document

【问题讨论】:

    标签: javascript reason rescript


    【解决方案1】:

    要调用 JS 函数,您需要使用 ReScript 的 JS interop。在这种情况下,您可以使用 external 关键字和 @val/@scope 属性来获取调用时将调用 document.createElement 的 ReScript 函数:

    @val @scope(("window", "document"))
    external createElement: string => unit = "createElement"
    
    createElement("div")
    

    这将被转换为

    window.document.createElement('div');
    

    为了快速制作原型,您也可以只使用external 并直接与 RS Objects 等对象进行交互:

    @val external document: 'a = "document"
    
    document["createElement"]("div")
    

    查看interop cheatsheetdocs for external 了解更多常见模式。

    【讨论】:

    • 我按照上述建议使用external。我已将createElement 的返回值正确键入为Dom.element,但我无法访问Mozilla 上提到的outerHTML 之类的属性。你能告诉我我做错了什么吗?代码是here
    • ReScript 提供了Dom 模块作为一组通用的不透明类型,供低级 UI 库使用;就像the docs 上所说的那样,它们不提供任何实际功能。如果您想与 DOM 进行命令式交互,您需要在 JS 中编写大部分实际代码,然后为 ReScript 公开一些入口点(这就是 Dom opaque 类型的用途,以确保您的 RS代码传递期望值类型)。正如@mr-polywhirl 提到的,阻力最小的途径是使用现有的库,如 React。
    • @vinay-deshmukh ,您需要先了解几个不同的概念,然后才能理解您在这里做错了什么。 Stack Overflow 不是一个讨论的好地方。我强烈建议在 ReScript 论坛上提出这个问题,人们可以在那里进行扩展讨论:forum.rescript-lang.org。最后,如果你只是想立即开始使用,试试github.com/reasonml-community/bs-webapi-incubator
    【解决方案2】:

    你可以使用 bs-webapi

    open Webapi.Dom
    open Belt
    
    document
    ->Document.asHtmlDocument
    ->Option.flatMap(document => document->HtmlDocument.body)
    ->Option.map(body => {
      let root = document->Document.createElement("div", _)
      root->Element.setId("app")
      root->Element.appendChild(body)
    })
    ->ignore
    
    

    【讨论】:

    • “小写”document 来自哪里?
    【解决方案3】:

    由于 re-script 由 React (JSX) 提供支持,而不是标准的 ECMA JavaScript,我认为您不能使用像 document.createElement 这样的调用。

    相反,您应该通过以下方式create the element

    let element = <h1> {React.string("Hello World")} </h1>
    

    这会转换成以下内容:

    var element = React.createElement("h1", undefined, "Hello World");
    

    我修改了默认的 Playground 脚本:

    module Button = {
      @react.component
      let make = (~count: int) => {
        let times = switch count {
        | 1 => "once"
        | 2 => "twice"
        | n => Belt.Int.toString(n) ++ " times"
        }
        let msg = "Click me " ++ times
        let element = <button> {React.string(msg)} </button>
        element
      }
    }
    

    【讨论】:

    • React.createElement 不等同甚至不接近 document.createElement。正如我所提到的,我正在尝试在 JS 中使用 ReScript,而不是在 React 项目中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多