Использование ItemFragment немного излишне, так как itemProperty
фрагмента никогда не изменится (новый фрагмент будет создаваться для каждого элемента при каждом изменении libraryItemsProperty
. Однако, если логика вашего представления для каждого элемента существеннаэтот подход обеспечит чистый способ отделить и содержать эту логику, так что это может стоить того. Вот полный пример, который вы можете использовать в качестве отправной точки.
class ShapeItemFragment : ItemFragment<ShapeItem>() {
val shapeModel = ShapeItemModel().bindTo(this)
override val root = stackpane {
label(shapeModel.name)
}
}
class ShapeItem(name: String) {
val nameProperty = SimpleStringProperty(name)
}
class ShapeItemModel : ItemViewModel<ShapeItem>() {
val name = bind(ShapeItem::nameProperty)
}
class LibraryViewModel : ViewModel() {
val libraryItemsProperty = SimpleListProperty<ShapeItem>(
listOf(
ShapeItem("Shape 1"),
ShapeItem("Shape 2")
).observable()
)
}
class LibraryView : View("Current Library") {
val shapeLibraryViewModel: LibraryViewModel by inject()
override val root = anchorpane {
flowpane {
bindChildren(shapeLibraryViewModel.libraryItemsProperty) { shapeItem ->
val itemFragment = find<ShapeItemFragment>()
itemFragment.itemProperty.value = shapeItem
itemFragment.root
}
}
}
}
Несколько более легкая версия будетпередать параметр в ваш фрагмент вручную и просто расширить Fragment:
class ShapeItemFragment : Fragment() {
val item: ShapeItem by param()
override val root = stackpane {
label(item.nameProperty)
}
}
Вы все еще можете привязать изменения к свойствам внутри ShapeItem
, так как базовый элемент не изменится (как видно из ItemFragment) в любом случае.
Ваш bindChildren
оператор будет выглядеть так:
bindChildren(shapeLibraryViewModel.libraryItemsProperty) { shapeItem ->
find<ShapeItemFragment>(ShapeItemFragment::item to shapeItem).root
}