使用ScalaJS js.Object.defineProperty

时间:2017-09-11 12:48:18

标签: scala.js

使用ScalaJS,我需要创建一个js.Object,其中包含一个值为函数的属性,所以我已经这样做了:

@JSGlobal
class EventPropertyDescriptor(n: Int, rpt: WeatherReportBuilder) extends PropertyDescriptor() {
  this.configurable = true
  this.enumerable   = true
  this.value        = buildSlippyMap("mapDiv" + n, rpt)
  this.writable     = true
  this.get          = null
  this.set          = null
}


var onAfterRenderingHandler = Object.defineProperty(new Object(), "onAfterRendering", new EventPropertyDescriptor(counter, report))

buildSlippyMap返回Function0[Unit]

的位置

但是这不会编译,因为据我所知,js.PropertyDescriptor已被实现为特征,而Scala特征无法直接转换为JavaScript ...

我该怎么办?

由于

Chris W

2 个答案:

答案 0 :(得分:2)

您的代码段中的问题是您将EventPropertyDescriptor定义为(本机)@JSGlobal类。你真的告诉编译器:“在JavaScript的全局范围内有一个名为EventPropertyDescriptor的类,我没有编写,请使用那个”。实际上,您应该收到大量有关该代码段的编译器警告。

如果PropertyDescriptor是一个非原生的JS特征 - 它在Scala.js 1.x但不在0.6.x--中,你可以写:

val onAfterRenderingHandler = js.Object.defineProperty(
    new js.Object(),
    "onAfterRendering",
    new js.PropertyDescriptor {
      configurable = true
      enumerable = true
      value = buildSlippyMap("mapDiv" + counter, report)
      writable = true
    }))

但是,由于Scala.js 1.x仍然在里程碑中,并且您可能使用的是0.6.x,因此您将不得不使用更脏的路线:

val propDescriptor = js.Dynamic.literal(
    configurable = true,
    enumerable = true,
    value = buildSlippyMap("mapDiv" + counter, report),
    writable = true
).asInstanceOf[js.PropertyDescriptor]
val onAfterRenderingHandler = js.Object.defineProperty(
    new js.Object(),
    "onAfterRendering",
    propDescriptor)

另请参阅@ gzm0的回答,特别是询问您是否需要defineProperty

答案 1 :(得分:0)

您只需要在子类中定义字段即可。此外,它还需要是一个非本地类:

class EventPropertyDescriptor(n: Int, rpt: WeatherReportBuilder) 
   extends PropertyDescriptor {
  val configurable = true
  val enumerable = true
  val value = buildSlippyMap("mapDiv" + n, rpt)
  val writable = true
}

var onAfterRenderingHandler = Object.defineProperty(new Object(), 
    "onAfterRendering", new EventPropertyDescriptor(counter, report))

虽然,你不能这样做吗?

var onAfterRenderingHandler = new js.Object {
  val onAfterRendering = buildSlippyMap("mapDiv" + counter, report)
}