如何在 scalajs 中进行模式匹配 event.data
how to pattern match event.data in scalajs
我想在我的 window#postMessage
处理程序上匹配不同的事件,但我无法匹配本机特征。那么我该如何解决这个问题:
@js.native
trait XY extends js.Object {
val x: AnyVal = js.native
val y: AnyVal = js.native
}
@js.native
trait DataEvent extends js.Object {
val c: String = js.native // chart
val s: String = js.native // dataSet
val d: XY = js.native // xy data
val x: Seq[XY] = js.native // eXtra data
}
object ChartApi extends JSApp {
def receiveMessage(event: Any): Unit = {
event match {
case DataEvent => ???
case _ => println("else")
}
println(s"lala $event")
}
def main(): Unit = {
// add window event handler
dom.window.addEventListener("message", (event: MessageEvent) => receiveMessage(event.data), false)
println("Hello world!")
}
}
我在不同的 iframe 中有不同的图表,我需要通过 postMessage 发送 "add this data" 或 "clear data" 等事件。
JS traits 在 run-time 没有标识,这就是为什么你不能直接测试任意对象是否是 JS traits 的实例的原因。
相反,您需要采用 JS 方式,并测试是否存在唯一标识特征表示的接口的字段,以及其他可能的选择。例如:
if (event.hasOwnProperty("d")) {
// it must be a DataEvent, because the alternatives do not have a 'd' field
val e = event.asInstanceOf[DataEvent]
...
} else {
...
}
不过,通常我们不喜欢这样做。因此,在具有多种此类消息的消息传递协议中,我们通常有一个明确的 messageType
字段或类似的东西。如果您确保所有 DataEvent
消息都有一个 messageType = "data"
字段,您可以:
if (event.messageType == "data") {
val e = event.asInstanceOf[DataEvent]
...
} else {
...
}
您可以在提取器中对此 "type test" 进行编码:
object DataEvent {
def unapply(event: Any): Option[DataEvent] =
if (event.messageType == "data") Some(event.asInstanceOf[DataEvent])
else None
}
然后您可以像这样在模式匹配中使用它:
event match {
case DataEvent(event) => ???
case _ => println("else")
}
最后,您可能需要考虑一个 serialization/pickling 库来处理您所有的消息,例如 类。有关此类库的列表,请参阅 https://www.scala-js.org/libraries/libs.html。
我想在我的 window#postMessage
处理程序上匹配不同的事件,但我无法匹配本机特征。那么我该如何解决这个问题:
@js.native
trait XY extends js.Object {
val x: AnyVal = js.native
val y: AnyVal = js.native
}
@js.native
trait DataEvent extends js.Object {
val c: String = js.native // chart
val s: String = js.native // dataSet
val d: XY = js.native // xy data
val x: Seq[XY] = js.native // eXtra data
}
object ChartApi extends JSApp {
def receiveMessage(event: Any): Unit = {
event match {
case DataEvent => ???
case _ => println("else")
}
println(s"lala $event")
}
def main(): Unit = {
// add window event handler
dom.window.addEventListener("message", (event: MessageEvent) => receiveMessage(event.data), false)
println("Hello world!")
}
}
我在不同的 iframe 中有不同的图表,我需要通过 postMessage 发送 "add this data" 或 "clear data" 等事件。
JS traits 在 run-time 没有标识,这就是为什么你不能直接测试任意对象是否是 JS traits 的实例的原因。
相反,您需要采用 JS 方式,并测试是否存在唯一标识特征表示的接口的字段,以及其他可能的选择。例如:
if (event.hasOwnProperty("d")) {
// it must be a DataEvent, because the alternatives do not have a 'd' field
val e = event.asInstanceOf[DataEvent]
...
} else {
...
}
不过,通常我们不喜欢这样做。因此,在具有多种此类消息的消息传递协议中,我们通常有一个明确的 messageType
字段或类似的东西。如果您确保所有 DataEvent
消息都有一个 messageType = "data"
字段,您可以:
if (event.messageType == "data") {
val e = event.asInstanceOf[DataEvent]
...
} else {
...
}
您可以在提取器中对此 "type test" 进行编码:
object DataEvent {
def unapply(event: Any): Option[DataEvent] =
if (event.messageType == "data") Some(event.asInstanceOf[DataEvent])
else None
}
然后您可以像这样在模式匹配中使用它:
event match {
case DataEvent(event) => ???
case _ => println("else")
}
最后,您可能需要考虑一个 serialization/pickling 库来处理您所有的消息,例如 类。有关此类库的列表,请参阅 https://www.scala-js.org/libraries/libs.html。