在scala.js

时间:2015-05-06 20:58:40

标签: scala.js

我刚刚开始使用Scala.js并尝试使用简单的d3.js语句:

d3.select("body").append("svg")

为了获得最小的工作版本,我克隆了scala.js教程,将d3.js添加到index-fastopt.html中,并在ScalaJSExample.scala中添加了以下代码(从https://github.com/spaced/scala-js-d3借用):< / p>

trait Selection extends js.Array[js.Any] {
  var append: js.Function1[String, Selection] = js.native
}

trait Base extends js.Object {
  def select(selector: String): Selection = js.native
}

object Global extends scalajs.js.GlobalScope {
  val d3: Base = js.native
}

object ScalaJSExample extends js.JSApp {
  import Global._
  def main(): Unit = { 
    d3.select("body").append("svg")
  }

}

但是此代码失败并显示错误:

Uncaught TypeError: this.select is not a function
   _a.append @ d3.v3.min.js:3

该声明的fastOpt版本是:

 (0, $g["d3"]["select"]("body")["append"])("svg")

对我来说,看起来append的调用this不是选择,因此追加调用失败。

以下版本的代码可以正常工作,但非常麻烦且非d3惯用,因为d3很大程度上依赖于方法链:

trait Selection extends js.Array[js.Any] {
  var append: js.ThisFunction1[Selection, String, Selection] = js.native
}

trait Base extends js.Object {
  def select(selector: String): Selection = js.native
}

object Global extends scalajs.js.GlobalScope {
  val d3: Base = js.native
}

object ScalaJSExample extends js.JSApp {
  import Global._
  def main(): Unit = { 
    val sel = d3.select("body")
    sel.append(sel, "svg")
}

有没有更好的方法将选择作为this传递给追加,这允许我保留d3的流畅界面风格?

1 个答案:

答案 0 :(得分:2)

原始外观类型错误,这就是您遇到麻烦的原因。 append的定义应为def,而不是函数类型的var

trait Selection extends js.Array[js.Any] {
  def append(param: String): Selection = js.native
}

然后你的链式调用将起作用并产生适当的JS。