我刚刚开始使用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的流畅界面风格?
答案 0 :(得分:2)
原始外观类型错误,这就是您遇到麻烦的原因。 append
的定义应为def
,而不是函数类型的var
:
trait Selection extends js.Array[js.Any] {
def append(param: String): Selection = js.native
}
然后你的链式调用将起作用并产生适当的JS。