将case类转换为js.Object的最佳方法

时间:2016-03-07 15:17:40

标签: scala.js

说我有一个案例类:

case class Name(first: String, last: String)
val n1 = Name("John", "Doe")
val n2 = Name("Mary", "Doe")

我有一个java脚本对象:

@js.native
trait MyJSObject extends js.Object { 
  def add(name: js.Object): Unit = js.native 
}

这样名称的格式应为

{"first":"John","last":"Doe"}

将我的case对象转换为js.Object的最佳方法是什么?

我知道这可以通过upickle.write()将其转换为json String来实现,所以我想我的问题是这是最好的方法吗?

2 个答案:

答案 0 :(得分:7)

如果您控制案例类,则只需向其添加@JSExportAll注释:

@JSExportAll
case class Name(first: String, last: String)

这将创建名为firstlast的属性。请注意, 与简单对象相同。但是,根据add方法的作用,它足够(并且比转换为JSON并再次解析更轻量级)。

如果您需要交叉编译案例类,可以在JVM项目中包含scalajs-stubs库。它将提供虚拟注释(不会写入.class文件)。

如果您需要js.Object,可以使用导出类型检查程序:

val x = Name("foo", "bar")
js.use(x).as[js.Object]

这甚至适用于定义所需字段的特征:

@js.native
trait Options extends js.Object {
  def first: String = js.native
  def last: String = js.native
}

val x = Name("foo", "bar")
js.use(x).as[Options]

如果类型之间存在不匹配,则js.use(x).as调用将失败(即,如果Options定义了Name未定义的字段)。

答案 1 :(得分:0)

使用uPickle

val jsValue: Js.Value = upickle.Types.writeJs[Name](n1)
val jsObject: js.Any = upickle.json.writeJs(jsValue).asInstanceOf[js.Any]