承上篇
上篇实作完成执行结果如上图所示,蓝色区块为该学生成绩,红色区块为新增成绩编辑画面,全部程序皆在StudentView.kt
里,接下来我们要将蓝色及红色部份分离出来。
GradeViewComponent.kt
,将蓝色区块程序码剪下,完成程序如下 :package com.example.vok
import com.github.mvysny.karibudsl.v10.*
import com.vaadin.flow.component.HasComponents
import com.vaadin.flow.component.dependency.CssImport
import com.vaadin.flow.component.dependency.StyleSheet
import com.vaadin.flow.component.orderedlayout.VerticalLayout
class GradeViewComponent: KComposite() {
var studentId: Long = 0
set(value) {
field = value
refresh()
}
private lateinit var grades: VerticalLayout
private val root = ui{
verticalLayout {
isMargin = false
h2("成绩")
grades = verticalLayout()
}
}
fun refresh() {
grades.removeAll()
Student.getById(studentId).grades.fetch().forEach {
grades.html("<p>" +
"<strong>学期:</strong>${it.description} " +
"<strong>国文:</strong>${it.mandarin} " +
"<strong>英文:</strong>${it.english} " +
"<strong>数学:</strong>${it.math} " +
"<strong>体育:</strong>${it.pe}" +
"</p>")
}
}
}
fun HasComponents.grandsViewComponent(block: GradeViewComponent.()->Unit = {}) = init(GradeViewComponent(), block)
这里多了studentId
属性值供外部设定,设定studentId
属性後呼叫refresh()
方法,清除成绩div区块後,再读取成绩资料以html语法直接替换显示。
GradeEditorComponent.kt
package com.example.vok
import com.github.mvysny.karibudsl.v10.*
import com.vaadin.flow.component.HasComponents
import com.vaadin.flow.component.button.Button
class GradeEditorComponent : KComposite() {
var gradeCreatedListener: () -> Unit = {}
lateinit var student: Student
private val gradeBinder = beanValidationBinder<Grade>()
private lateinit var addGradeButton: Button
private val root = ui {
verticalLayout {
text("新增成绩")
textField("学期") {
bind(gradeBinder).bind(Grade::description)
placeholder = "第一学期"
}
numberField("国文") {
bind(gradeBinder).bind(Grade::mandarin)
}
numberField("英文") {
bind(gradeBinder).bind(Grade::english)
}
numberField("数学") {
bind(gradeBinder).bind(Grade::math)
}
numberField("体育") {
bind(gradeBinder).bind(Grade::pe)
}
addGradeButton = button("新增") {
onLeftClick { addGrade() }
}
}
}
private fun addGrade() {
val grade = Grade()
if (gradeBinder.validate().isOk && gradeBinder.writeBeanIfValid(grade)) {
grade.student_id = student.id
grade.save()
gradeBinder.readBean(Grade())
gradeCreatedListener()
}
}
}
fun HasComponents.gradeEditorComponent(block: GradeEditorComponent.() -> Unit = {}) =
init(GradeEditorComponent(), block)
StudentView.kt
package com.example.vok
import com.github.mvysny.karibudsl.v10.*
import com.vaadin.flow.component.Text
import com.vaadin.flow.component.icon.VaadinIcon
import com.vaadin.flow.router.BeforeEvent
import com.vaadin.flow.router.HasUrlParameter
import com.vaadin.flow.router.Route
import com.vaadin.flow.router.RouterLink
@Route("student", layout = MainLayout::class)
class StudentView: KComposite(), HasUrlParameter<Long> {
private lateinit var editLink: RouterLink
private lateinit var name: Text
private lateinit var gender: Text
private lateinit var birthday: Text
private lateinit var gradeView: GradeViewComponent
private lateinit var gradeEditor: GradeEditorComponent
private val root = ui {
verticalLayout {
routerLink(VaadinIcon.ARROW_LEFT, null, viewType = AllStudentsView::class)
div {
strong("姓名 : "); [email protected] = text("")
}
div {
strong("性别 : "); [email protected] = text("")
}
div {
strong("生日 : "); [email protected] = text("")
}
gradeView = grandsViewComponent()
gradeEditor = gradeEditorComponent {
gradeCreatedListener = { gradeView.refresh() }
}
editLink = routerLink(VaadinIcon.EDIT,null)
}
}
override fun setParameter(event: BeforeEvent?, studentId: Long) {
val student = Student.getById(studentId)
gradeView.studentId = studentId
gradeEditor.student = student
name.text = student.name
gender.text = student.gender.toString()
birthday.text = student.birthday.toString()
editLink.setRoute(EditStudent::class, student.id!!)
}
companion object {
fun navigateTo(studentId: Long) = navigateToView(StudentView::class, studentId)
}
}
gradeView
、gradeEditor
分别为蓝色、红色区块
以下程序会使用到简单 html、css 概念
除了可使用html()方法输出 HTML 外,亦可使用 Karibu-DSL提供的其他方法。红色区块要将它改为div table 显示
fun refresh() {
grades.removeAll()
grades.apply {
div("table") {
div("tr") {
div("td") { strong("学期") }
div("td") { strong("国文") }
div("td") { strong("英文") }
div("td") { strong("数学") }
div("td") { strong("体育") }
}
}
}
Student.getById(studentId).grades.fetch().forEach {
grades.apply {
div("table") {
div("tr") {
div("td") { label("${it.description}") }
div("td") { label("${it.mandarin}") }
div("td") { label("${it.english}") }
div("td") { label("${it.math}") }
div("td") { label("${it.pe}") }
}
}
}
}
div後面括号内为css class name ,表示我们需要一个 css档。在Vaadin flow framework 专案结构,css档放置在 web/frontend/,新增 table.css
.table {
display: table;
border-collapse: collapse;
width: 500px;
margin:0px;
}
/* tr */
.tr{
display: table-row; border:0px; margin:0px;
}
/* td , th */
.td {
display: table-cell;
width: 180px;
}
css 已经准备好了,该如何引入呢?请开启 GradeViewComponent.kt
,在最前面加上标示
@CssImport("frontend://table.css")
class GradeViewComponent : KComposite() {
(略)
}
这样就完成自订样式(style)的画面了。虽然看起来似乎复杂了一点,但需要自订Style时非常的好用,执行结如果下
参考资料 : css产生器
本日程序已上传GitHub
>>: 【Day09-填空】漏漏缺缺欠欠填填删删补补——面对缺失值的处理方式
今天学习进度还是 鸟哥的 Linux 私房菜 -- DNS Server /etc/nsswitch...
案例说明及适用场景 客户往来记录,属於商机管理的一环,一个客户不见得袛有一次商机,而一个商机的完成必...
天亮了 昨晚是平安夜 关於迷雾森林故事 粉红烟花三个月 由於黑洞把12只 animal 吸走後的烟 ...
我们已经使用过"="给变量命名,今天主要演示的是如何使用"return...
前言 很开心能够确实每天发文,并且持续30天成功完赛! 虽然这些天的发文大多都是过去学习中累计下来的...