scala-json 在 scala.js 中反初始化

scala-json unserialize in scala.js

我正在尝试使用 scala-json https://github.com/MediaMath/scala-json[ 将 JSON 从 Ajax 请求转换为 Scala.js 中的案例 class =16=]

这是我的 classes:

sealed trait Result
sealed trait Error extends Result
sealed trait Msg extends Result
case class MsgData(msg: Seq[String], args: Seq[Int]) extends Msg

case class CommentError(@name("obj.comment") comment: Seq[MsgData]) extends Error

这是我尝试转换的方式:

import json._
implicit val msgDataAcc = ObjectAccessor.create[MsgData]
implicit val commentErrorAcc = ObjectAccessor.create[CommentError]

println("here2")
val errors = JValue.fromString(req.responseText).toObject[CommentError]
println("here3")

此代码在转换后的字符串中静静地死去,"here3" 从未打印到控制台。

这是我来自服务器的JSON:

{"obj.comment":[{"msg":["error.minLength"],"args":[10]}],"obj.name":[{"msg":["error.path.missing"],"args":[]}]}

我做错了什么?如何解决这个问题?

所以我猜这是 scala-js。如果您将整个事情包装在 Try 中并打印出堆栈跟踪,则在 scala-js 应用程序的顶层(入口点)发生的任何异常并不总是正确回显(取决于 environment/browser)在捕获期间,您应该成功地看到抛出异常。

上面的主要问题是您需要为案例 类 定义 'accessors'。有两种方法可以做到这一点,一种是通过为每种类型添加一个隐式来开箱即用,另一种方法需要宏天堂,并为您提供一种更简单的方法来为 case 类.[=12= 定义访问器]

这里是正常的非宏观天堂方式:

case class MsgData(msg: Seq[String], args: Seq[Int]) extends Msg
object MsgData {
  implicit val acc = ObjectAccessor.create[MsgData]
}

case class CommentError(@name("obj.comment") comment: Seq[MsgData]) extends Error
object CommentError {
  implicit val acc = ObjectAccessor.create[CommentError]
}

隐式可以放在任何地方(遵循 scala 隐式的一般规则)。将它们放在伴随对象中是保证隐式可以在任何地方找到的最佳方式,无需特殊导入或任何需要。

与 circe 等使用 shapeless 自动派生工厂的其他库相比,这是 'less magical',有时会以一种臃肿的方式。 scala-json 旨在为扩展目的保持访问器可见,但这确实会导致一些明确的样板文件。

这可以使用宏观天堂来减少:

@accessor case class MsgData(msg: Seq[String], args: Seq[Int]) extends Msg
@accessor case class CommentError(@name("obj.comment") comment: Seq[MsgData]) extends Error

这与上面的代码完全相同,我们只是利用 macro-paradise 自动将隐式 'acc' 字段添加到伴随对象。