自动更新Vaadin 8中活页夹中相关计算属性的显示

罗勒酒

当使用Binder在Vaadin 8与具有只读属性计算其值导出从另一个属性豆,我怎样才能得到一个TextField自动更新衍生计算结果显示当驱动属性有其价值变化?

在以下示例中,当用户更改“出生年份”字段时,如何获取“年龄”字段以更新其计算?

在此处输入图片说明

Vaadin 8 的完整工作示例。

package com.example.val;

import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.data.Binder;
import com.vaadin.data.converter.StringToIntegerConverter;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.*;

import javax.servlet.annotation.WebServlet;
import java.time.LocalDate;
import java.time.ZoneId;

/**
 * This UI is the application entry point. A UI may either represent a browser window
 * (or tab) or some part of a html page where a Vaadin application is embedded.
 * <p>
 * The UI is initialized using {@link #init(VaadinRequest)}. This method is intended to be
 * overridden to add component to the user interface and initialize non-component functionality.
 */
@Theme ( "mytheme" )
public class MyUI extends UI {

    Person person;
    Binder < Person > binder;

    @Override
    protected void init ( VaadinRequest vaadinRequest ) {
        // Data model
        this.person = new Person ( "Jean-Luc", 1955 );

        // Widgets
        final TextField nameField = new TextField ( "Type the person’s name here:" );
        final TextField yearOfBirthField = new TextField ( "Type the year of birth here:" );
        final TextField ageField = new TextField ( "Approximate age:" );
        ageField.setReadOnly ( true );
        final Label beanToString = new Label ( );

        // Binder
        this.binder = new Binder <> ( );
        binder.forField ( nameField )
                .bind ( Person:: getName, Person:: setName );
        binder.forField ( yearOfBirthField )
                .withConverter ( new StringToIntegerConverter ( "Input must be Integer" ) )
                .bind ( Person:: getYearOfBirth, Person:: setYearOfBirth );
        binder.forField ( ageField )
                .withConverter ( new StringToIntegerConverter ( "" ) )
                .bind ( Person:: getAge, null );
        binder.setBean ( this.person );

        final Button button = new Button ( "Save" );
        button.addClickListener ( event -> {
            if ( binder.validate ( ).isOk ( ) ) {
                // With `setBear`, the Person object is always up-to-date as long as there are no validation errors.
                // MyBackend.updatePersonInDatabase(person);
                beanToString.setValue ( this.person.toString ( ) );
            } else {  // Else bean flunks validation.
                beanToString.setValue ( "The Person bean has invalid state." );
            }
        } );


        this.setContent ( new VerticalLayout ( nameField, yearOfBirthField, ageField, button, beanToString ) );
    }

    @WebServlet ( urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true )
    @VaadinServletConfiguration ( ui = MyUI.class, productionMode = false )
    public static class MyUIServlet extends VaadinServlet {
    }
}

class Person {
    private Integer yearOfBirth;
    private String name;


    public Person ( String name_, Integer yearOfBirth_ ) {
        this.name = name_;
        this.yearOfBirth = yearOfBirth_;
    }

    public String getName ( ) {
        return name;
    }

    public void setName ( String name ) {
        this.name = name;
    }

    public Integer getYearOfBirth ( ) {
        return yearOfBirth;
    }

    public void setYearOfBirth ( Integer yearOfBirth ) {
        this.yearOfBirth = yearOfBirth;
    }

    // Read-only property 'age', calculated rather than stored.
    public Integer getAge ( ) {
        LocalDate today = LocalDate.now ( ZoneId.systemDefault ( ) );
        Integer years = ( today.getYear ( ) - this.yearOfBirth );
        return years;
    }

    @Override
    public String toString ( ) {
        return "Person{ " +
                "yearOfBirth=" + yearOfBirth +
                ", age='" + this.getAge ( ) + "'" +
                ", name='" + name + "'" +
                " }";
    }
}
阿克塞尔·迈耶

我找到的最简单的方法是yearOfBirthField通过以下方式修改 的绑定代码

binder.forField(yearOfBirthField)
    .withConverter(new StringToIntegerConverter("Input must be Integer"))
    .bind(Person::getYearOfBirth, (Setter<Person, Integer>) (person1, integer) -> {
                person1.setYearOfBirth(integer);
                ageField.setValue(person1.getAge().toString());
            });

这有效地将 绑定yearOfBirthFieldyearOfBirth属性并更新age人员 bean属性。以任何方式更改 person bean 的成员,例如通过调用person.setYearOfBirth(1977)对字段没有直接影响。Vaadin 的更新机制只在一个方向上起作用。字段修改会传输到 bean,反之则不然。

编辑

在 Vaadin 8 中,没有内置方法可以在 bean 属性更改时自动更新字段。yearOfBirthField的值更改时,新值将传播到 person bean,并且 person 的yearOfBirth成员通过绑定自动更改。但是之后 Vaadin 不会获取 bean 的所有绑定字段的当前值。因此ageField未更新且不反映当前值。

因此,要ageField显示更新的值,您必须以ageField编程方式更新您可以在 binder 上再次设置整个 bean,这将导致所有 getter 被调用,但最简单的方法是在设置后设置 ageField 的值yearOfBirth这是在 setter 绑定的建议修改中完成的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

ListBox中的项目不会自动更新

来自分类Dev

在angularjs中自动更新范围变量

来自分类Dev

符号变量在theano中自动更新

来自分类Dev

Java中的软件自动更新器

来自分类Dev

UpdateView中的自动更新子弹字段

来自分类Dev

Java中的软件自动更新程序

来自分类Dev

自动更新Word文档中的文本

来自分类Dev

Kubuntu中的全自动更新

来自分类Dev

angularJS中的自动更新值

来自分类Dev

WPF 中的 Listview 不会自动更新

来自分类Dev

领事中的自动更新键值?

来自分类Dev

计算列不会自动更新

来自分类Dev

JavaScript:自动更新length属性

来自分类Dev

Windows 8何时安装自动更新?

来自分类Dev

无法自动更新Java 8

来自分类Dev

如何自动更新表中的相关字段?

来自分类Dev

使用TPrototypeBindSource自动更新对象中的属性

来自分类Dev

如何在C#中自动更新属性

来自分类Dev

标签中的文字是否可以自动更新显示内容

来自分类Dev

自动布局在显示时自动更新位置

来自分类Dev

自动布局在显示时自动更新位置

来自分类Dev

添加并显示根据实体计算并自动更新的元素

来自分类Dev

自动更新结构体中的指针值

来自分类Dev

如何在Opencart中禁用货币自动更新?

来自分类Dev

在ReactJS中自动更新用户界面

来自分类Dev

如何在AWS中自动更新AMI映像?

来自分类Dev

自动更新SQL Server中的列值

来自分类Dev

自动更新R参考类中的字段(数据成员)

来自分类Dev

在Android Studio中自动更新AAR文件