当前位置: 首页 > 知识库问答 >
问题:

Vaadin绑定对象

严兴言
2023-03-14

我正在尝试将文本字段绑定到对象。我做了一些研究,找到了这个答案。

public class Person {

 String name;
 String surname;
 Address address;

 // assume getters and setters
}

public class Address {

 String street;

 // assume getter and setters
}

然后,您可以像这样绑定街道地址:

Binder<Person> binder = new Binder<>();

TextField streetAddressField = new TextField();

// bind using lambda expressions

binder.bind(streetAddressField,
person -> person.getAddress().getStreet(),
(person, street) -> person.getAddress().setStreet(street));

我将Street实例化为什么值(在最后一行代码中)?

以上是我找到的例子。我的代码如下——我有一个联系类:

@Entity
public class Contact {

    @Id
    @GeneratedValue
    private Long id;

    private String firstName;

    private String lastName;

    private String phoneNumber;


    @ManyToOne (cascade = {CascadeType.ALL})
    @JoinColumn(name="phoneType_typeId")
    private PhoneType phoneType;

    public Contact(){

    }

    public Contact(String firstName, String lastName, String phoneNumber, PhoneType type) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.phoneNumber = phoneNumber;
        this.phoneType = type;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public PhoneType getPhoneType() {
        return phoneType;
    }

    public void setPhoneType(PhoneType phoneType) {
        this.phoneType = phoneType;
    }

    @Override
    public String toString() {
        return String.format("Contact[firstName='%s', lastName='%s', phoneNumber='%s', phoneType = '%s']",
                firstName, lastName, phoneNumber, phoneType);
    }
}

然后我有一个phoneType类:

@Entity
@Table(name="phoneType")
public class PhoneType {


    @Id
    @GeneratedValue
    @Column(name = "typeId")
    private Long id;

    private String type;

    public PhoneType(String type){
        this.type = type;
    }

    public PhoneType(){}

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @Override
    public String toString() {
        return type;
    }
}

然后在联系人编辑器中,我试图将phoneType绑定到文本字段:

@SpringComponent
@UIScope
public class ContactEditor extends VerticalLayout {

    private final ContactRepository repository;

    private Contact contact;

    TextField firstName = new TextField("First name");
    TextField lastName = new TextField("Last name");
    TextField phoneNumber = new TextField("Phone number");
    TextField phoneType = new TextField( "Phone type");

    Button save = new Button("Save", VaadinIcons.CHECK);
    Button cancel = new Button("Cancel");
    Button delete = new Button("Delete", VaadinIcons.TRASH);
    CssLayout actions = new CssLayout(save, cancel, delete);

    Binder<Contact> binder = new Binder<>(Contact.class);


    @Autowired
    public ContactEditor(ContactRepository repository, Contact contact) {
        this.repository = repository;
        this.contact = contact;
        String type = contact.getPhoneType().getType();

        addComponents(firstName, lastName, phoneNumber, phoneType, actions);

        // bind using naming convention
        **binder.bind(phoneType, contact.getPhoneType().getType(), contact.getPhoneType().setType(type));**
        binder.bindInstanceFields(this);

        // Configure and style components
        setSpacing(true);
        actions.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
        save.setStyleName(ValoTheme.BUTTON_PRIMARY);
        save.setClickShortcut(ShortcutAction.KeyCode.ENTER);

        // wire action buttons to save, delete and reset
        save.addClickListener(e -> repository.save(contact));
        delete.addClickListener(e -> repository.delete(contact));
        cancel.addClickListener(e -> editContact(contact));
        setVisible(false);
    }

    public interface ChangeHandler {

        void onChange();
    }

    public final void editContact(Contact c) {
        if (c == null) {
            setVisible(false);
            return;
        }
        final boolean persisted = c.getId() != null;
        if (persisted) {
            // Find fresh entity for editing
            contact = repository.findById(c.getId()).get();
        }
        else {
            contact = c;
        }
        cancel.setVisible(persisted);

        // Bind customer properties to similarly named fields
        // Could also use annotation or "manual binding" or programmatically
        // moving values from fields to entities before saving
        binder.setBean(contact);

        setVisible(true);

        // A hack to ensure the whole form is visible
        save.focus();
        // Select all text in firstName field automatically
        firstName.selectAll();
    }

    public void setChangeHandler(ChangeHandler h) {
        // ChangeHandler is notified when either save or delete
        // is clicked
        save.addClickListener(e -> h.onChange());
        delete.addClickListener(e -> h.onChange());
    }


}

在联系人编辑器中,包含在**中的行(即 binder.bind(电话类型,联系人.getPhoneType().getType(),联系人.getPhoneType().setType(类型)))中包含的行给我一个错误 - “不存在类型变量 FIELDVALUE 的实例,因此字符串符合值提供者。

共有2个答案

呼延鸿畅
2023-03-14

我不知道这是不是你的要求,但我认为你缺少的是你没有把活页夹绑在任何豆子上。

您已经创建了绑定器,并告诉了textfield绑定了哪个属性,但是现在您需要告诉绑定器哪个是他的bean。

像这样:

Person yourPerson = new Person(); //or get person from database somehow
yourPerson.setAddress(new Address());
yourPerson.getAddress().setStreet("Road cool code, 404");
binder.setBean(yourPerson);

这应该会奏效……如果不行,请更好地解释你需要什么。;)

单淳
2023-03-14

这条线

binder.bind(phoneType, contact.getPhoneType().getType(), contact.getPhoneType().setType(type));

无法编译,因为方法参数与任何bind方法都不匹配,并且第三个参数中存在非法的Java表达式。根据你的问题,你只是忘记了使用lambdas。尝试:

binder.bind(phoneType, c -> c.getPhoneType().getType(), (c, t) -> c.getPhoneType().setType(t));

看看方法签名:

public <FIELDVALUE> Binder.Binding<BEAN,FIELDVALUE> bind(HasValue<FIELDVALUE> field,
                                                     ValueProvider<BEAN,FIELDVALUE> getter,
                                                     Setter<BEAN,FIELDVALUE> setter)

它期望ValueProviderSetter作为第二和第三个参数。这些接口只有一个方法要实现,因此您可以使用lambda将它们传递给bind

 类似资料:
  • 在使用springboot的vaadin flow项目中,我遇到了一个问题,即带有组合框的枚举值无法绑定。我在下面提供了我的代码。这里有人能帮我吗? 组合盒实例化: 绑定代码:

  • 英文原文:http://emberjs.com/guides/object-model/bindings/ 一个绑定在两个属性之间建立了一个连接,当其中一个发生改变时,另外一个将自动更新为新的值。绑定连接同一对象中属性,也可以连接不同对象的属性。不同于其他一些也实现了类似绑定的框架,Ember.js中的绑定可以在任意对象中使用,而并不紧紧局限于视图和模型。 建立一个双向的关联最简单的方法是添加一个

  • 对于剑道中的绑定行为,似乎有一个相当奇特的设计决策。 我试图绑定一个null值到一个下拉列表。如果(远程来源的)值为null,那么Kendo将生成对象以绑定到该值,例如,使用下拉列表的data-value-field/value。这使得保存修改后的视图模型非常不可靠,因为现在整个对象将被传输,而不是简单的数据类型。 示例:为。从下拉列表中选择值后,如 值(JSON)然后是而不是 有人对此有一个好的

  • 主要内容:示例对象数据绑定是指将JSON映射到任何JAVA对象。 示例 让我们看看对象数据绑定的行动。 这里将JAVA对象直接映射到JSON,反之亦然。参考实现代码:GsonTester.java - 执行上面示例代码,得到以下结果 -

  • 我对使用模板引擎Thymeleaf的Spring 4 Portlet有问题。 我想将一个工作正常的现有servlet转换为portlet。我使用Thymeleaf在JSP文件的表单中编辑对象。 <代码> 是迄今为止有效的生成操作URL。正如您所假设的,我想在我的控制器中使用。我尝试了许多方法来实现这一点,例如: 不幸的是,在调用操作后,对象尚未填充其属性。我真的不想知道,但我不知道如何使用Thym

  • 我正在使用Guice开发一个小型web框架。我有一个Router对象,一旦初始化,它就会公开一个getControllerClasses()方法。我必须循环所有这些动态返回的类,以使用Guice绑定它们。 我绑定路由器: 但是,我如何在一个模块中获得绑定的路由器实例,以便也可以绑定其getControllerClasses()方法返回的类? 我能够在模块中获取路由器实例的唯一方法是,将该实例绑定到