如何将 Javascript 中的 JQuery 翻译成 ScalaJS (scalajs-jquery)
How to translate JQuery in Javascript to ScalaJS (scalajs-jquery)
在我的 ScalaJS 项目中我使用 Semantic-UI with scala-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(其他人可能会解决 #1):要记住的关键是它确实是一个 JavaScript 数据结构;将其视为 JSON 会分散注意力。所以你通常使用 strongly-typed 门面实例化它,就像 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-readable 类型,而不是内部 Scala 类型。
对于外包装,基本上是一样的——像这样的 deeply-nested 结构有点麻烦,但基本上只是为每个 strongly-typed 创建一个小外观特征的问题水平。
对于 weakly-typed 级别(例如,dog
,我假设它没有在库中定义),您可能想要使用 js.Dynamic.literal
,它可以让您创建任意JavaScript 数据结构,完全没有强类型。 (当然,您也可以这样做来创建 Rules
,但是如果过度使用它,您将失去使用 Scala 的很多好处。)
请注意,以上内容的详细信息因您使用的 Scala.js 版本而异——有关详细信息,请参阅文档。但这就是它的大致运作方式...
根据 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
}
这是它的用法 - 检查动态 cardNumber
和 cardCVC
:
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)
在我的 ScalaJS 项目中我使用 Semantic-UI with scala-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(其他人可能会解决 #1):要记住的关键是它确实是一个 JavaScript 数据结构;将其视为 JSON 会分散注意力。所以你通常使用 strongly-typed 门面实例化它,就像 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-readable 类型,而不是内部 Scala 类型。
对于外包装,基本上是一样的——像这样的 deeply-nested 结构有点麻烦,但基本上只是为每个 strongly-typed 创建一个小外观特征的问题水平。
对于 weakly-typed 级别(例如,dog
,我假设它没有在库中定义),您可能想要使用 js.Dynamic.literal
,它可以让您创建任意JavaScript 数据结构,完全没有强类型。 (当然,您也可以这样做来创建 Rules
,但是如果过度使用它,您将失去使用 Scala 的很多好处。)
请注意,以上内容的详细信息因您使用的 Scala.js 版本而异——有关详细信息,请参阅文档。但这就是它的大致运作方式...
根据 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
}
这是它的用法 - 检查动态 cardNumber
和 cardCVC
:
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)