【问题标题】:Dynamic calls to JavaScript in Scala.jsScala.js 中对 JavaScript 的动态调用
【发布时间】:2018-04-28 17:41:12
【问题描述】:

我想知道如何在 Scala.js 中进行动态操作。比如看教程中的jQuery例子,我的理解是你在scala中定义如下:

object TutorialApp extends JSApp {
  def appendPar(msg: String) = {
    jQuery("body").append("<p>" + msg + "</p>")
  }
  def main(): Unit = {
    appendPar("Hello World")
 }
}

这是在编译时静态生成的所有内容。但是我没有看到任何可以动态设置消息参数的方法(例如从数据库中读取它)。

【问题讨论】:

    标签: scala scala.js


    【解决方案1】:

    我不知道从数据库中读取它。这超出了这个问题的范围(或者你需要重新表述这个问题)。也许是 AJAX 调用或其他什么?

    但要从例如&lt;input&gt; 标记中读取它,您需要执行以下操作:

    def main(): Unit = {
      val msg = jQuery("#myinput").value()
      appendPar(msg)
    }
    

    (虽然在这种情况下,它在 main 方法中可能没有任何意义,但这不是重点。)

    我的意思是,msg 只是一个 val(就像 JS 中的 var 但不可变)。您可以根据需要从任何动态信息源中获取它。

    编辑:

    如果你想在渲染页面的时候访问一些服务器动态生成的数据,你可以这样做:

    首先,让您的服务器在生成的 HTML 的 &lt;script&gt; 标记中将数据生成为全局 var。比如:

    <script type="text/javascript">
    var mydata = {
      msg: "Some text generated dynamically by the server"
    }
    </script>
    

    确保在调用Scala.js 的main() 函数之前发出此脚本标记!

    然后,您可以从 Scala.js 使用js.Dynamic 接口访问这些数据:

    import scala.scalajs.js
    
    val mydata = js.Dynamic.global.mydata
    val msg = mydata.msg.asInstanceOf[String]
    

    如果您的数据始终具有相对静态的结构,则为它们声明自己a facade type 可能会很有用:

    @JSName("mydata")
    object MyData extends js.Object {
      val msg: String = ???
    }
    

    然后您无需借助Dynamic API 即可访问它:

    val msg = MyData.msg
    

    【讨论】:

    • 我想要实现的是将通过服务器端处理获得的信息传回。但是当所有的 JavaScript 都是静态生成时,我看不出这是怎么可能的。
    • 仍然可以动态生成一些JS,放到生成的HTML中。如果将其存储在全局变量中,则可以从 Scala.js 访问此全局变量。
    • 我找不到有关如何执行此操作的任何文档?
    【解决方案2】:

    添加(并试图概括)sjrd's answer:要在 JavaScriptType 的对象上调用 javaScriptMethod,您首先要为其编写 type facade

    import scala.scalajs.js
    import scala.scalajs.js.annotation.JSName
    
    @js.native
    @JSName("JavaScriptType")
    class MyType() extends js.Object {
      def javaScriptMethod(someParam: String) = js.native
    }
    

    之后,在客户端使用 Scala 的 JavaScript 代码就是小菜一碟了:

    val myObject = new MyType()
    myObject.javaScriptMethod("Yippie")
    

    作为一个具体示例,要在您的 Scala.js 应用程序中使用 Stack Overflow 的 Markdown 转换器 Pagedown,您首先要为其创建类型外观:

    @js.native
    @JSName("Markdown.Converter")
    class MarkdownConverter() extends js.Object {
      def makeHtml(txtUsingMarkdown: String): String = js.native
    }
    

    如果你正在使用 this great tutorial project 学习 Scala.js,你可以像这样在 Settings.scala 中声明对 Pagedown 的依赖:

    val jsDependencies = Def.setting(Seq(
      "org.webjars.bower" % "pagedown" % "1.1.0" / "Markdown.Converter.js",
      //...
    

    那么你可以简单地做

    val html = new MarkdownConverter().makeHtml("this is *nice*")
    

    这是另一个例子,我们调用SparkMD5 的静态方法。

    我们定义了一个object,而不是前面示例中的class。此外,我们可以省略 @JSName 注释,因为我们的 Scala 类型与 JavaScript 类型同名:

    @js.native
    object SparkMD5 extends js.Object {
      def hash(str: String, raw: Boolean = false): String = js.native
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-31
      • 1970-01-01
      • 2021-07-06
      相关资源
      最近更新 更多