JavaFX中的MVVM。具有数据模型的控件 [英] MVVM in JavaFX. Controls that have a data model

查看:331
本文介绍了JavaFX中的MVVM。具有数据模型的控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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 Contacts 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆