如何将JQuery中的JQuery翻译成ScalaJS(scalajs-jquery)

时间:2018-04-03 13:47:43

标签: jquery semantic-ui scala.js

在我的ScalaJS项目中,我使用Semantic-UIscala-js-jquery

我用它来修补JQuery:

  // Monkey patching JQuery
  @js.native
  trait SemanticJQuery extends JQuery {
    def dropdown(params: js.Any*): SemanticJQuery = js.native
    def popup(params: js.Any*): SemanticJQuery = js.native
    // and more
  }

  // Monkey patching JQuery with implicit conversion
  implicit def jq2semantic(jq: JQuery): SemanticJQuery = jq.asInstanceOf[SemanticJQuery]

例如$('select.dropdown').dropdown();

转换为jQuery(".ui.dropdown").dropdown(js.Dynamic.literal(on = "hover"))

我现在的问题是如何翻译这个:

$('.ui.form')
  .form({
    fields: {
      dog: {
        identifier: 'dog',
        rules: [
          {
            type: 'adminLevel[2]',
            prompt: 'You must be at least a level-2 admin to add a dog'
          }
        ]
      }
    }
  });

2 个答案:

答案 0 :(得分:2)

首先考虑更容易的问题#2(其他人可能会解决#1):要记住的关键是它实际上是 JavaScript 数据结构;把它想象成JSON是一种分心。因此,您通常使用强类型的外观来实例化它,就像其他JavaScript一样。

您可以找到关键文档here,但粗略地说,外观类似于:

trait Rules extends js.Object {
  def `type`: String
  def prompt: js.UndefOr[String] = js.undefined
}

我在此处强制使用type,并将prompt视为可选,以显示处理这些字段的方式的差异。 (因为“type”是Scala中的关键字,你必须解决这个问题;我认为反引号会起作用。)

然后通过创建匿名子类实例来实例化它,如下所示:

new Rules {
  override val `type` = "adminLevel[2]"
  override val prompt = "You must be at least a level-2 admin to add a dog"
}

基本上,它是相当普通的Scala,但extends js.Object是编译器魔术 - 它告诉编译器输出应该是JavaScript可读类型,而不是内部Scala类型。

对于外包装器,它基本上是相同的 - 这样的深层嵌套结构是一个轻微的麻烦,但它基本上只是为每个强类型级别创建一个小的外观特征。

对于弱类型的级别(例如dog,我假设它没有在库中定义),您可能想要使用js.Dynamic.literal,它允许您创建任意JavaScript数据结构,没有强烈的打字。 (当然,你也可以这样做来创建Rules,但如果你使用Scala,那么你将失去使用Scala的大部分好处。)

请注意,上述详细信息会根据您使用的Scala.js版本而有所不同 - 有关详细信息,请参阅文档。但这就是它的工作原理......

答案 1 :(得分:0)

按照Justin du Coeur的回答,它奏效了!

为了完整起见,这里是整个解决方案(因为它是静态和动态部分的组合):

trait Form extends js.Object {
  def fields: js.Object
}

trait Field extends js.Object {
  def identifier: String
  def rules: js.Array[Rule]
}

trait Rule extends js.Object {
  def `type`: String
  def prompt: js.UndefOr[String] = js.undefined
}

以下是其用法 - 检查动态cardNumbercardCVC

val form = new Form {
  val fields: js.Object = js.Dynamic.literal (
    cardNumber = new Field {
      val identifier: String = "cardNumber"
      val rules: js.Array[Rule] = js.Array(new Rule {
        val `type`: String = "empty"
      })
    },
    cardCVC = new Field {
      val identifier: String = "cardCVC"
      val rules: js.Array[Rule] = js.Array(new Rule {
        val `type`: String = "validate['cardCVC']"
        override val prompt = "You must a valid CVC - see ..."
      })
    }
)}

jQuery(".ui.form").form(form)