Call jquery .each method from scala.js

2019-08-31 07:22发布

问题:

Is this doc out-dated? http://www.scala-js.org/doc/calling-javascript.html Can't seem to get this right in intellij:

import org.scalajs.dom.html
import org.scalajs.dom
import org.scalajs.dom.raw.HTMLElement
import scala.scalajs.js
import js.JSConverters._

import fr.iscpif.scaladget.d3._
import fr.iscpif.scaladget.mapping._

import scala.scalajs.js
import scala.scalajs.js.annotation.JSExport
import org.scalajs.jquery.jQuery

/**
 * Created by IDEA on 31/10/15.
 */
@JSExport
object LearnD3 {
  @JSExport
  def main(div: html.Div): Unit = {
    jQuery("#list > li").each((x, y) => y)
  }
}

First dom.HTMLElement doesn't seem to exist. There is org.scalajs.dom.raw.HTMLElement, but even if I import that there is a type mismatch:

回答1:

You need to specify the types of the parameters. The following code works:

val x = jQuery("#list > li").each((i: js.Any, y: Element) => y)

You may note that index i is of the type Any and usually you would expect a index to be of the type Int. Because of this kind of problems, jquery-facade was born: a more strongly typed facade for jquery. I highly recommend it. The same code in jquery-facade:

 import org.querki.jquery._

 ... 

 val x = $("#list > li").each((y: Element, i: Int) => y)

Or, if you don't need the i index:

 val x = $("#list > li").each((y: Element) => y)

Or you want y type to be infered:

 val x = $("#list > li").foreach(y => y)


回答2:

Actually, that was always just intended to be a conceptual example of how to use ThisFunction -- it's never actually been correct for the loosely-typed scala-js-jquery facade. (It's closer to the jquery-facade version, although at the moment that still requires Element rather than HTMLElement, since that is what the JQuery docs say. I should think about whether that ought to be tightened; I'm honestly not sure.)

But basically, that was never intended to be literal code, and I believe it's never worked as such. It's just an illustration of the syntax of ThisFunction.

As for HTMLElement, yes, that's now under raw. You would usually refer to that as dom.html.Element now. In that respect, it is out of date. But regardless, the example should be taken more as a concept than literal code. (And yes, the example might use rewriting; PRs are generally happily accepted.)