在我的ScalaJS项目中,我使用Semantic-UI和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'
}
]
}
}
});
答案 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
}
以下是其用法 - 检查动态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)