如何为在ScalaJS中发出事件的方法定义外观

时间:2015-02-16 10:53:11

标签: facade scala.js

我正在为pouchdb

编写scalajs facade

代码:https://gist.github.com/chandu0101/62013de47bf5ee4d2412

如何为API名称changes定义外观,该名称会发出事件并返回取消方法..

1 个答案:

答案 0 :(得分:3)

定义Scala.js外观类型就是为JavaScript API提供静态类型。通常,JavaScript 的文档提及类型,因此可以很容易地将其转换为正式定义。

在这种情况下,changes方法返回EventEmitter,这是您需要的第一件事。让我们定义这种类型,特别是它的on方法:

class EventEmitter extends js.Object {
  def on(event: String, listener: js.Function): this.type = js.native
  ...
}

遗憾的是,我们必须对listener的类型非常不精确,因为实际类型将在很大程度上取决于事件字符串以及该发射器的特定用途。一般来说,我们现在无法预测任何事情。

EventEmitter的文档没有提到cancel()方法,这有点奇怪,因为显然可以在changes返回的发射器上调用该方法。因此,我们将为changes返回的特定发射器定义子类型:

trait ChangesEventEmitter extends EventEmitter {
  def cancel(): Unit = js.native
}

我们还可以利用这种专业特性为特定事件启用更精确的侦听器类型。在这种情况下,让我们为change事件:

执行此操作
object ChangesEventEmitter {
  implicit class ChangesEventEmitterEvents(
      val self: ChangesEventEmitter) extends AnyVal {
    def onChange(listener: js.Function1[js.Dynamic, Any]): self.type =
      self.on("change", listener)
  }
}

最后,您需要options方法的db.changes参数的类型。类型本身通常是具有许多不可变字段的特征:

trait DBChangesOptions extends js.Object {
  val include_docs: js.UndefOr[Boolean] = js.native
  val limit: js.UndefOr[Int] = js.native
  ...
}

构造这种类型的实例,您可以使用默认参数在伴随对象中使用apply方法(请参阅this SO question),或者您可以为它创建一个类似Builder的类。

现在,我们终于可以声明changes方法了:

def changes(options: DBChangesOptions = ???): ChangesEventEmitter = js.native