Этот вопрос касается проекта Kotlin JS, в котором используется плагин внешнего интерфейса Kotlin.
Я хочу использовать некоторые компоненты пользовательского интерфейса из библиотеки Vaadin Components .
IУ меня есть два вопроса по этому поводу:
(1) Как лучше всего включить веб-компоненты в Kotlin JS
=> для моего полного кода, см. ссылку на источник ниже.Таким образом, соответствующие данные:
build.gradle.kts
kotlinFrontend {
npm {
dependency("@vaadin/vaadin-grid")
}
}
vaadin.grid.Imports.kt
@file:JsModule("@vaadin/vaadin-grid")
@file:JsNonModule
package vaadin.grid
external class GridElement {
companion object
}
Почему companion object
?Мне нужно это для обходного пути (см. Ниже).
foo.kt
fun main() {
document.getElementById("container")!!.append {
vaadin_grid {
attributes["id"] = "grid"
}
}
initUI()
}
fun initUI() {
// Force the side-effects of the vaadin modules. Is there a better way?
console.log(GridElement)
val grid = document.querySelector("#grid") /* ?? as GridElement ?? */
}
console.log
- это уродливый обходной прием, которого я хочу избежать.Если я ничего не делаю с GridElement, то он просто не включается в мой пакет.
DSL vaadin_grid
определяется как пользовательский тег kotlinx.html, который не связан с кодом.
(2) Я хочу сохранить мой код как можно более типизированным, чтобы избежать asDynamic
, но когда я приводил HTMLElement
к элементу Vaadin, я получаю ClassCastExceptions (потому что GridElement
равно undefined
).
Например, я хочу написать что-то вроде этого:
val grid : GridElement = document.querySelector("#grid") as GridElement
grid.items = ... // vs grid.asDynamic().items which does work
Вот как я определяю внешний GridElement
vaadin / button / Imports.kt
@file:JsModule("@vaadin/vaadin-grid")
@file:JsNonModule
package vaadin.grid
import org.w3c.dom.HTMLElement
abstract external class GridElement : HTMLElement {
var items: Array<*> = definedExternally
}
build/node_modules/@vaadin/vaadin-grid/src/vaadin-grid.js
...
customElements.define(GridElement.is, GridElement);
export { GridElement };
Исходный пример
Для запуска:
Из корня репозитория git:
./gradlew 05-kt-frontend-vaadin:build && open 05-kt-frontend-vaadin/frontend.html