首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >vaadin 10推送标签不会更新

vaadin 10推送标签不会更新
EN

Stack Overflow用户
提问于 2018-08-22 22:24:31
回答 2查看 747关注 0票数 2

MainView包括InformationCOmponent:

代码语言:javascript
复制
@Push
@Route
public class MainView extends VerticalLayout {       
    InformationComponent infoComponent;

    public MainView(@Autowired StudentRepository studentRepo, @Autowired Job jobImportCsv, @Autowired JobLauncher jobLauncher, @Value("${file.local-tmp-file}") String inputFile) {     
    [...] // some stuffs

    infoComponent = new InformationComponent(studentRepo);
    add(infoComponent);
    }

    //update when job process is over
    private void uploadFileSuccceed() {
       infoComponent.update(myUploadComponent.getFile());
    }

InformationComponent:

代码语言:javascript
复制
public class InformationComponent extends HorizontalLayout {

    StudentRepository studentRepo;

    Label nbLineInFile = new Label();

    VerticalLayout componentLeft = new VerticalLayout();;
    VerticalLayout componentRight = new VerticalLayout();;

    public InformationComponent(StudentRepository studentRepo) {
    [...] // some init and style stuff

    addLine("Nombre de lignes dans le fichier", nbLineInFile);
    }

    private void addLine(String label, Label value) {
    componentLeft.add(new Label(label));
    componentRight.add(value);
    }

    public void update(File file) {
    try {


        long nbLines = Files.lines(file.toPath(), Charset.defaultCharset()).count();

        System.out.println("UPDATED! " +nbLines); // value is display in console ok!
        UI.getCurrent().access(() -> nbLineInFile.setText(nbLines)); // UI is not updated!!
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
  }
}

当我从MainView 调用时,标签不会在浏览器中更新。

代码语言:javascript
复制
UI.getCurrent().access(() -> nbLineInFile.setText(nbLines))

也尝试使用@Push(PushMode.MANUAL)和ui.push();但是也不能工作.

完整的源代码在这里:SpringBatch/tree/push-not-working

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-23 04:15:52

我怀疑这里的问题是uploadFileSuccceed()是从后台线程运行的,在这种情况下,UI.getCurrent()将返回null。这将导致一个NullPointerException,它要么会杀死后台线程,要么会被调用方捕获并默默忽略异常。另一种选择是,uploadFileSuccceed()是通过不同的浏览器窗口发生的,因此也是通过不同的UI实例发生的,这意味着更改将在错误的UI上下文中推送。

正因为如此,UI.getCurrent().access(...)通常是一种反模式,尽管不幸的是,它在旧示例中被广泛使用。

您可以通过在UI.getCurrent()方法的开头记录update的值,并将其与UI.getCurrent()的值(例如,在InformationComponent的构造函数中)进行比较来检查这是否是造成问题的原因。

要正确解决这个问题,您应该将正确的UI实例传递给所有触发后台处理启动的事件的整个链。您还应该注意,使用任何getUI()子类中可用的Component方法可能很有诱惑力,但是该方法并不是线程安全的,因此应该在后台线程中避免使用。

最后,我建议在这种情况下使用SpanText组件而不是Label。在Vaadin 10中,Label组件被更改为使用<label> HTML元素,这意味着它主要用作输入组件的标签。

票数 4
EN

Stack Overflow用户

发布于 2018-08-23 06:55:24

根据Leif提供的信息,您应该执行如下示例。

在运行时,当这个HorizontalLayout子类对象附加到父UI对象时,将调用它的onAttach方法。此时,我们可以通过存储UI的引用来记住UI,它是一个名为ui的成员变量。实际上,返回的是Optional而不是UI对象,因此我们需要测试null,尽管在onAttach点上它永远不应该是null。

代码语言:javascript
复制
public class InformationComponent extends HorizontalLayout {

    UI ui;

    StudentRepository studentRepo;

    Label nbLineInFile = new Label();

    VerticalLayout componentLeft = new VerticalLayout();;
    VerticalLayout componentRight = new VerticalLayout();;

    public InformationComponent(StudentRepository studentRepo) {
        [...] // some init and style stuff

        addLine("Nombre de lignes dans le fichier", nbLineInFile);
    }

    private void addLine(String label, Label value) {
        componentLeft.add(new Label(label));
        componentRight.add(value);
    }

    public void update(File file) {
    try {
        long nbLines = Files.lines(file.toPath(), Charset.defaultCharset()).count();

        System.out.println("UPDATED! " +nbLines); // value is display in console ok!
        this.ui.access(() -> nbLineInFile.setText(nbLines)); // UI is not updated!!
    } catch (IOException e) {
        throw new RuntimeException(e);
    } catch (UIDetachedException e) {
        // Do here what is needed to do if UI is no longer attached, user has closed the browser
    }

    @Override  // Called when this component (this `HorizontalLayout`) is attached to a `UI` object.
    public void onAttach() {
        ui = this.getUI().orElseThrow( () -> new IllegalStateException("No UI found, which should be impossible at point of `onAttach` being called.") );

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51975976

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档