[英]Tornadofx Javafx - How to reload a view / component
因此,這是一個基本問題。
我想要實現的是從另一個視圖刷新視圖。
可以說我有一個EmployeeTableView視圖,該視圖通過執行REST API調用來顯示員工的表格表示形式。
在另一個視圖中,我有一個過濾器EmployeeFilterView,其中有性別,薪水范圍,員工類型等。
我還有一個userContext對象,用於存儲用戶首選項。 因此,默認情況下,我已將性別過濾器的值存儲為Male,工資范圍存儲為ALL,等等。該對象作為參數發送到EmployeeTableView。
加載EmployeeTableView時,我使用userContext值進行restAPI調用以獲取員工詳細信息。 這樣就可以了。 現在,將性別過濾器更改為“女性”,並在userContext中分配此值。
現在,如果我可以使用userContext對象重新加載EmployeeTableView,則restapi調用將獲取更新后的值。
但是我該怎么做呢?
如果有的話,也建議一個更好的方法。
EventBus是對此的一種有效解決方案。 另一種方法是將ViewModel或Controller用作UserContext對象,並讓其包括實際可觀察到的雇員列表,然后將該列表綁定到EmployeeTableView
的TableView
。 每當上下文中的列表更新時,TableView也會更新。
篩選器視圖將在UserContext中調用一個函數以執行實際的REST調用,並基於該調用更新員工列表。
您可以創建一個單獨的EmployeeQuery對象,該對象可以注入到EmployeeFilterView
和UserContext
以便它可以提取選定的篩選器值來執行查詢。 該查詢對象包含要傳遞給服務器的所有搜索參數的列表。
如果對您的體系結構有意義,您也可以考慮創建一個單獨的作用域以使這些組件分離。
究竟如何定義這些組件主要取決於口味,這是一個建議。 我將ControlsFX的RangeSlider
用於模擬搜索UI。
為了更容易地想象這是如何聯系在一起的,下面是一個屏幕截圖:
(所有名字和薪水都是虛構的:)
/**
* The employee domain model, implementing JsonModel so it can be fetched
* via the REST API
*/
class Employee : JsonModel {
val nameProperty = SimpleStringProperty()
var name by nameProperty
val salaryProperty = SimpleIntegerProperty()
var salary by salaryProperty
val genderProperty = SimpleObjectProperty<Gender>()
var gender by genderProperty
override fun updateModel(json: JsonObject) {
with (json) {
name = getString("name")
salary = getInt("salary")
gender = Gender.valueOf(getString("gender"))
}
}
}
enum class Gender { Male, Female }
/**
* Container for the list of employees as well as a search function called by the filter
* view whenever it should update the employee list.
*/
class EmployeeContext : Controller() {
val api: Rest by inject()
val query: EmployeeQuery by inject()
val employees = SimpleListProperty<Employee>()
fun search() {
runAsync {
FXCollections.observableArrayList(Employee().apply {
name = "Edvin Syse"
gender = Gender.Male
salary = 200_000
})
//api.post("employees/query", query).list().toModel<Employee>()
} ui {
employees.value = it
}
}
}
/**
* Query object used to define the query sent to the server
*/
class EmployeeQuery : ViewModel(), JsonModel {
val genderProperty = SimpleObjectProperty<Gender>(Gender.Female)
var gender by genderProperty
val salaryMinProperty = SimpleIntegerProperty(50_000)
var salaryMin by salaryMinProperty
val salaryMaxProperty = SimpleIntegerProperty(250_000)
var salaryMax by salaryMaxProperty
val salaryDescription = stringBinding(salaryMinProperty, salaryMaxProperty) {
"$$salaryMin - $$salaryMax"
}
override fun toJSON(json: JsonBuilder) {
with(json) {
add("gender", gender.toString())
add("salaryMin", salaryMin)
add("salaryMax", salaryMax)
}
}
}
/**
* The search/filter UI
*/
class EmployeeFilterView : View() {
val query: EmployeeQuery by inject()
val context: EmployeeContext by inject()
override val root = form {
fieldset("Employee Filter") {
field("Gender") {
combobox(query.genderProperty, Gender.values().toList())
}
field("Salary Range") {
vbox {
alignment = Pos.CENTER
add(RangeSlider().apply {
max = 500_000.0
lowValueProperty().bindBidirectional(query.salaryMinProperty)
highValueProperty().bindBidirectional(query.salaryMaxProperty)
})
label(query.salaryDescription)
}
}
button("Search").action {
context.search()
}
}
}
}
/**
* The UI that shows the search results
*/
class EmployeeTableView : View() {
val context: EmployeeContext by inject()
override val root = borderpane {
center {
tableview(context.employees) {
column("Name", Employee::nameProperty)
column("Gender", Employee::genderProperty)
column("Salary", Employee::salaryProperty)
}
}
}
}
/**
* A sample view that ties the filter UI and result UI together
*/
class MainView : View("Employee App") {
override val root = hbox {
add(EmployeeFilterView::class)
add(EmployeeTableView::class)
}
}
我最終使用了Tornadofx-> EventBus
基本上,當我更改任何過濾器時,都會觸發一個用更新后的值重建Node的even。
不確定該方法是否正確,這就是為什么仍要開放討論的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.