Как перевести класс Javascript в ScalaJS

#javascript #scala #scala.js

#javascript #scala #scala.js

Вопрос:

У меня есть этот простой код Javascript:

 import Modeler from 'bpmn-js/lib/Modeler';

import diagramXML from './diagram.bpmn';

const modeler = new Modeler({
  container: '#canvas'
});

modeler.importXML(diagramXML);
  

При открытии в браузере отображается диаграмма.

Я хочу сделать это в ScalaJS, но я что-то пропустил.

Вот мой код:

 @JSImport("resources/diagram.bpmn", JSImport.Default)
@js.native
object DiagramXML extends js.Object

object Main {

  @JSExportTopLevel("main")
  def main(): Unit = {
    val modeler = new Modeler(js.Object(
      "container" -> "#canvas"
    ))

   modeler.importXML(DiagramXML.toString)
 }
}
  

Вот мой фасад для Modeler :

 @js.native
@JSImport("bpmn-js/lib/Modeler", "Modeler")
class BpmnJS(options: js.Object) extends js.Object {

  def importXML(xml: String): js.Promise[Any] = js.native

}
  

Когда я отлаживаю, xml загружается правильно. Все, чего не хватает, это то, что он правильно отображается в DOM.

Ответ №1:

Я могу определить две проблемы в вашем переводе. Первый из них — это import of bpmn-js . Импорт JS

 import Modeler from 'bpmn-js/lib/Modeler';
  

который должен быть переведен в

 @JSImport("bpmn-js/lib/Modeler", JSImport.Default)
  

согласно документации по переводу import на @JSImport .

Другая проблема более тонкая. При вызове new Modeler у вас есть

 js.Object(
  "container" -> "#canvas"
)
  

который (возможно, к сожалению) компилируется, но не делает того, что вы думаете. Он создает кортеж Scala из двух строк, который передается функции JavaScript Object(...) , которая фактически возвращает его как есть (потому что кортеж Scala уже является объектом).

Вам нужен был объект JavaScript с полем container , который вы можете записать как

 new js.Object {
  val container = "#canvas"
}
  

Еще лучшим способом сделать это было бы сделать объект options статически типизированным на фасаде:

 class BpmnJS(options: BpmnJSOptions) extends js.Object {
  ..
}

trait BpmnJSOptions extends js.Object {
  var container: js.UndefOr[String] = js.undefined
}
  

Таким образом, вы сможете вызвать его как

 new BpmnJS(new BpmnJSOptions {
  container = "#canvas"
})
  

Комментарии:

1. спасибо за эту работу — интересно то, что она работала только при использовании предложенного BpmnJSOptions вами.