JavaFX中的MVVM。具有数据模型的控件 [英] MVVM in JavaFX. Controls that have a data model
问题描述
我在fxml文件中定义了一个TableView,但是我无法指定该表的列,因为该表将具有一些数据模型方面的知识,并且会违反MVVM。我创建了一个类,该类提供TableColumn的集合并提供数据模型。我想相对于表中的选定项目更改按钮状态。如何在不违反MVVM规则的情况下执行此操作?
I defined a TableView in the fxml file, but I can't specify a columns of the table, because the table will have some knowledge of data model and it would violate the MVVM. I created a class that provides a collection of TableColumn and provide a data model. I want to change button state relative to selected item in the table. How to do it without breaking the MVVM rules?
推荐答案
为解释如何使用MVVM创建表,我使用了联系人表为例。 Contact
类可能看起来像这样:
To explain how tables can be created with MVVM I use a "Contacts" table as example. The Contact
class could look like this:
class Contact {
private String firstName;
private String lastName;
// Getter/Setters
}
Contact
类是一个实体,属于模型。 MVVM规则规定,View / CodeBehind不应显示或使用它。
相反,我将创建一个新类 ContactTableRow
,该类包装了 Contact
:
The Contact
class is an entity and belongs to the Model. The MVVM rules say that it shouldn't be visible or used by the View/CodeBehind.
Instead I would create a new class ContactTableRow
that wraps a Contact
:
class ContactTableRow {
private Contact contact;
ContactTableRow(Contact contact) {
public String getFirstName() {
return contact.getFirstName();
}
// getter for Lastname
}
类属于ViewModel层。对于ViewModels,访问和使用模型类是合法的。
Conceptually this class belongs to the ViewModel layer. For ViewModels it's legal to access and use model classes.
在您的View类/代码后面,您现在可以将这个新类用于TableView:
In your View class/CodeBehind you can now use this new class for the TableView:
class ContactsView {
@FXML
private TableView<ContactTableRow> table;
}
这也满足了MVVM的规则,因为View可以使用ViewModel类。现在,您可以在实际的ViewModel中创建 ObservableList< ContactTableRow>项目
和 ObjectProperty< ContactTableRow> selectedItem
:
This is also satisifies the rules of MVVM because the View can use ViewModel classes. In your actual ViewModel you can now create an ObservableList<ContactTableRow> items
and a ObjectProperty<ContactTableRow> selectedItem
:
class ContactViewModel {
private ObservableList<ContactTableRow> items = ...
private ObjectProperty<ContactTableRow> selectedItem = ...
// property accessor methods
}
现在,您可以在View类中将viewModel属性与表视图连接:
In your View class you can now connect the viewModel properties with the table view like this:
class ContactsView {
@FXML
private TableView<ContactTableRow> table;
private ContactsViewModel viewModel = ...
public void initialize() {
table.setItems(viewModel.itemsProperty());
viewModel.selectedItemProperty().bind(
table.getSelectionModel().selectedItemProperty());
}
现在唯一要做的就是在ViewModel中创建一些逻辑以从数据库中加载实际的 Contact
,将其转换为 ContactTableRow
实例,并将其放入您的项目
列表。
The only thing to be done now is to create some logic in your ViewModel to load actual Contact
s from your database, convert the into ContactTableRow
instances and put them into your items
list.
通过这种方法,您的View独立于实际的模型类。在这个简单的示例中, ContactTableRow
类看起来很麻烦,但是在实际使用案例中,这可能变得非常有用。它将表与实际模型类分离。这样,您可以在单个表中显示来自多个实体的数据,并且如果将来数据结构发生变化,则只需重构行类,而不需要重构整个表。
ViewModel独立于实际的UI特定类。 viewModel提供的是UI应该做什么的抽象定义:有一些数据的列表,可以选择该数据的一个项目。如何将此数据列表呈现给用户与ViewModel不相关。
将来,View可以将 TableView
替换为 ListView
或其他某些组件,而无需更改ViewModel 。
With this approach your View is independent from actual model classes. In this simple example it may look like the ContactTableRow
class is overhead but in real world use cases this can become really useful. It decouples the table from the actual model classes. This way you can show data from multiple entites in a single table and if the structure of your data changes in the future you only need to refactor the row class and not the whole table.
The ViewModel is independent from actual UI specific classes. What the viewModel provides is an abstract definition of what the UI should do: There is a list of some data and a single item of this data can be selected. How this list of data is presented to the user is not relevant to the ViewModel.
The View could replace the TableView
with a ListView
or some other component in the future without changing the ViewModel.
您可以在 mvvmFX 库:联系人示例包含使用此技术的主/细节视图。
You can find an example of this approach in the examples section of the mvvmFX library: The contacts example contains a master-detail view which uses this technique.
这篇关于JavaFX中的MVVM。具有数据模型的控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!