scala.js:映射一个 JSON-通过 jQuery 加载的数组

scala.js: map a JSON-Array loaded via jQuery

我是 scala.js 的新手,在理解它时遇到了一些麻烦。目前我坚持以下(非异步标志是故意的):

val req = jQuery.ajax(literal(
    url = ...,
    `type` = "GET",
    async = false).asInstanceOf[JQueryAjaxSettings]
)
val res = req.selectDynamic("responseText").toString

实际上,响应是一个 JSON 数组。数组中的每个项目都有一个名为 name 的字段(在其他字段中),这是有保证的,不需要验证。我想要做的是 .map 每个条目到它的名称字段,这样得到的输出是 Array[String] 只包含元素的名称。我怎样才能做到这一点?

嗯。请记住,异步标志早已被弃用;我没有意识到它甚至可以使用了。但把它当作阅读,这就是大致涉及的内容。 (显然未经测试;根据您的实际情况进行调整。)

我从你的描述中得到的印象是结果是一个JSON字符串,它实际上是对一个数组进行编码。既然如此,第一步就是解析:

val rawArray:js.Dynamic = JSON.parse(res)

解析JSON字符串,给你一个js.Dynamic,也就是JS对象的"raw"形式。此时,Scala.js对其结构一无所知。

接下来,您应该向 Scala.js 描述数组中每个 元素 的结构:

@js.native
trait MyStruct extends js.Object {
  val name:String = js.native
}

这就是您如何指导 Scala.js 关于 JavaScript 类型。您告诉它此类型有一个名为 "name" 的 属性,它是一个字符串。您可以根据需要添加或不添加该类型的其他字段——因为听起来您只关心 name,您不需要列出其余部分。

然后,你告诉 Scala.js 你的 rawArray 到底是什么:

val myArray = rawArray.asInstanceOf[js.Array[MyStruct]]

asInstanceOf 不会 改变 任何东西——它只是向 Scala.js、"I know that this js.Dynamic is actually an Array of MyStruct" 声明。所以现在你有 myArray,这是一个 js.Array[MyStruct],你可以正常使用 map

val myNames = myArray.map(_.name)

当您在 Scala.js 和原始 JavaScript 的边界操作时,这种情况很正常。由于 JS 级别是完全无类型的,而 SJS 级别是强类型的,因此您必须 "teach" SJS JS 级别的实际类型是什么。然后你可以在其余的 SJS 代码中假设这些类型...