如何在 KotlinJs 中生成主体中带有 `this.field=value` 的 javascript 函数
How to generate a javascript function with `this.field=value` in body, in KotlinJs
当我将 KotlinJS 与 riot 一起使用时,它需要如下函数来定义标签:
function (opts) {
var self = this
self.name = "sample"
self.message = "init-message"
self.onCreate = fun(opts: dynamic) {
self.message = opts.message
}
self.click = fun() {
self.message = "Clicked!"
}
}
虽然我可以这样写 Kotlin 代码:
fun(opts: dynamic) {
val self = js("this")
self.name = "sample"
self.message = "init-message"
self.onCreate = fun(opts: dynamic) {
self.message = opts.message
}
self.click = fun() {
self.message = "Clicked!"
}
}
但是你可以看到它有几个问题:
- 我们必须使用一些
js("this")
技巧
self.name
,self.message
,类似的,函数体中到处都是动态代码
如何避免它们?我想尽可能多地编写纯粹的、类型安全的 Kotlin 代码。
并且,是否可以预先定义一个结构更清晰的class,例如:
class MyTag {
val name = "sample"
var message = "init-message"
fun onCreate() {}
fun click() {}
}
我可以接受对 class 进行一些转换以生成所需的函数。
可能的解决方案可能会 js("this")
转换为已知的 kotlin 类型。
虽然 js()
仍然存在,但它的用法非常局限,而且代码实际上是 type-safe。
下面的代码生成了你在 js 中需要的东西
interface MyTag {
var name: String
var message: String
var onCreate: (dynamic) -> Unit
var click: () -> Unit
}
inline fun <T> builder(block: T.() -> Unit) = block(js("this"))
fun tagFunction(opts: dynamic) = builder<MyTag> {
name = "sample"
message = "init-message"
onCreate = { message = opts.message }
click = { message = "Clicked!" }
}
当我将 KotlinJS 与 riot 一起使用时,它需要如下函数来定义标签:
function (opts) {
var self = this
self.name = "sample"
self.message = "init-message"
self.onCreate = fun(opts: dynamic) {
self.message = opts.message
}
self.click = fun() {
self.message = "Clicked!"
}
}
虽然我可以这样写 Kotlin 代码:
fun(opts: dynamic) {
val self = js("this")
self.name = "sample"
self.message = "init-message"
self.onCreate = fun(opts: dynamic) {
self.message = opts.message
}
self.click = fun() {
self.message = "Clicked!"
}
}
但是你可以看到它有几个问题:
- 我们必须使用一些
js("this")
技巧 self.name
,self.message
,类似的,函数体中到处都是动态代码
如何避免它们?我想尽可能多地编写纯粹的、类型安全的 Kotlin 代码。
并且,是否可以预先定义一个结构更清晰的class,例如:
class MyTag {
val name = "sample"
var message = "init-message"
fun onCreate() {}
fun click() {}
}
我可以接受对 class 进行一些转换以生成所需的函数。
可能的解决方案可能会 js("this")
转换为已知的 kotlin 类型。
虽然 js()
仍然存在,但它的用法非常局限,而且代码实际上是 type-safe。
下面的代码生成了你在 js 中需要的东西
interface MyTag {
var name: String
var message: String
var onCreate: (dynamic) -> Unit
var click: () -> Unit
}
inline fun <T> builder(block: T.() -> Unit) = block(js("this"))
fun tagFunction(opts: dynamic) = builder<MyTag> {
name = "sample"
message = "init-message"
onCreate = { message = opts.message }
click = { message = "Clicked!" }
}