JavaFX中的MVVM.具有数据模型的控件

Ant*_*nio 2 design-patterns javafx mvvm

我在fxml文件中定义了一个TableView,但我无法指定表的列,因为该表将具有一些数据模型知识,并且它会违反MVVM.我创建了一个类,它提供了TableColumn的集合并提供了一个数据模型.我想更改相对于表格中所选项目的按钮状态.如何在不违反MVVM规则的情况下做到这一点?

Man*_*uky 10

为了解释如何使用MVVM创建表,我使用"Contacts"表作为示例.这个Contact类看起来像这样:

class Contact {
    private String firstName;
    private String lastName;
    // Getter/Setters
}
Run Code Online (Sandbox Code Playgroud)

所述Contact类是一个实体,属于模型.MVVM规则说它不应该被View/CodeBehind看到或使用.相反,我将创建一个新的类ContactTableRow,它包装一个Contact:

class ContactTableRow {
    private Contact contact;
    ContactTableRow(Contact contact) {
    public String getFirstName() {
        return contact.getFirstName();
    }
    // getter for Lastname
}
Run Code Online (Sandbox Code Playgroud)

从概念上讲,此类属于ViewModel层.对于ViewModels,访问和使用模型类是合法的.

在View类/ CodeBehind中,您现在可以将这个新类用于TableView:

class ContactsView {
    @FXML
    private TableView<ContactTableRow> table;

}
Run Code Online (Sandbox Code Playgroud)

这也符合MVVM的规则,因为View可以使用ViewModel类.在您的实际ViewModel中,您现在可以创建一个ObservableList<ContactTableRow> items和一个ObjectProperty<ContactTableRow> selectedItem:

class ContactViewModel {
    private ObservableList<ContactTableRow> items = ...
    private ObjectProperty<ContactTableRow> selectedItem = ...

    // property accessor methods
}
Run Code Online (Sandbox Code Playgroud)

在View类中,您现在可以将viewModel属性与表视图连接,如下所示:

class ContactsView {
    @FXML
    private TableView<ContactTableRow> table;

    private ContactsViewModel viewModel = ...

    public void initialize() {
        table.setItems(viewModel.itemsProperty());

        viewModel.selectedItemProperty().bind(
            table.getSelectionModel().selectedItemProperty());    
}
Run Code Online (Sandbox Code Playgroud)

现在唯一要做的就是在ViewModel中创建一些逻辑来Contact从数据库加载实际的s,将ContactTableRow实例转换为实例并将它们放入items列表中.

使用此方法,您的View独立于实际的模型类.在这个简单的例子中,它可能看起来像是ContactTableRow开销,但在现实世界的用例中,这可能变得非常有用.它将表与实际的模型类分离.这样,您可以在单个表中显示来自多个entites的数据,如果将来数据结构发生更改,您只需要重构行类而不是整个表.ViewModel独立于实际的UI特定类.viewModel提供的是UI应该做什么的抽象定义:有一些数据列表,可以选择这些数据的单个项目.如何向用户显示此数据列表与ViewModel无关.在不更改ViewModel的情况下,View可以在将来替换TableViewa ListView或其他组件.

您可以在mvvmFX库的示例部分中找到此方法的示例:contacts示例包含使用此技术的master-detail视图.