ScalaJS外观与JS和应用程序数据

时间:2017-06-06 21:42:34

标签: scala.js

我试图为jQuery插件(https://github.com/devbridge/jQuery-Autocomplete)编写一个外观。包括一些回调,它传递了我被建模为:

的对象
@js.native
trait AutocompleteSuggestion extends js.Object {
  val value: String = js.native
  val data : js.Any = js.native
}

图书馆需要访问value; data仅供我使用。我创建了对象,将它提供给库,并将它作为回调的参数返回给我。

我能够为创建这些对象做的最好的事情是

object AutocompleteSuggestion {
  def apply[T](value: String, data: T) = {
    literal(value = value, data = data.asInstanceOf[js.Any]).asInstanceOf[AutocompleteSuggestion]
  }
}

传递这些对象之一的回调通常看起来像

def onSelect(suggestion: AutocompleteSuggestion): Unit = {
  val cb = suggestion.data.asInstanceOf[CourseBasic]
  // do something with the data
}

有关如何改善这一点的任何建议?特别感觉就像我做了大量的演员。我在https://www.scala-js.org/doc/interoperability/facade-types.html的例子中没有看到 - 但这些例子也刻意避免使用除原始类型之外的任何内容。

1 个答案:

答案 0 :(得分:1)

我建议如下。基本上,通过为AutocompleteSuggestion类型提供类型参数,可以更好地键入data。另外,我们使它成为@ScalaJSDefined特征而不是@js.native(因为大多数JS特性应该是这样),以便我们可以以类型安全的方式实例化它:

import js.annotation._

@ScalaJSDefined
trait AutocompleteSuggestion[T] extends js.Object {
  val value: String
  val data: T
}

object AutocompleteSuggestion {
  def apply[T](value0: String, data0: T): AutocompleteSuggestion[T] = {
    new AutocompleteSuggestion[T] {
      val value: String = value0
      val data: T = data0
    }
  }
}

def onSelect(suggestion: AutocompleteSuggestion[CourseBasic]): Unit = {
  val cb = suggestion.data
  // do something with the data
}

Aaand,不是一个演员:)