在 play 框架模板的 scalajs 方法中使用案例 class 参数

Use case class parameter in scalajs method from play framework template

在我从播放框架 Scala/Twirl 模板 view/notify 移交的 scalajs 方法中使用 case class 类型的参数时出现 UndefinedBehaviorError:

@(note: Notification, ...)(implicit ...)
<!DOCTYPE html>
<html>
  <body>
    ...
    <script type="text/javascript" charset="utf-8">
      CommandsJS.notify('@note');
    </script>
  </body>
</html>

这里是案例class是:

abstract class Notification
case class Email(sender: String, title: String, body: String) extends Notification
case class SMS(caller: String, message: String) extends Notification

以及ScalaJs中定义的方法:

@JSExport
def notify(notification: Notification): Unit = {    
...
  notification match {
    case Email(email, title, _ )    => log.info(s"Email: $email")
    case SMS(number, message)       => log.info(s"SMS: $number")
  }
}

案例 class 在控制器中被实例化:

class AppCtrl ... {

  def sendNote = silhouette.UserAwareAction { implicit request =>
    Ok(views.html.notify(SMS("John","hi John"), ...))
  }
}

在 javascript 控制台中出现运行时错误:检测到未定义的行为:SMS(John,hi John) 不是 Notification 的实例。 任何 help/workaround 感谢 - 谢谢

简短的回答是:你不能那样做。

您正在 服务器 上呈现此 Play 模板,传递通知。您不能只将 Notification 嵌入 JavaScript 代码中,这就是您在这里所做的:

  CommandsJS.notify('@note');

并期待它能发挥作用。那不是 Notification -- 它是 JavaScript String(包含 note.toString 的值,它会按照您在模板),这就是您收到所看到的错误的原因。

要使这项工作有效,您必须先序列化 Notification(如 JSON 或其他),然后再将其传递到模板中,嵌入 that 作为 String 值,然后在客户端将其反序列化到 notify() 中。我偶尔会这样做,这有点麻烦,但没有什么用——你不能像这样通过模板将强类型的 Scala 对象从服务器传递到客户端...