Reputation: 13
e.g. while current is UI. After some async service done, and we want to push relevant change to component. e.g. model
current.access(new Command() {
@Override
public void execute() {
getElement().executeJs("this.widget.refresh(window.JSON.parse($0))", model);
}
});
no change on screen until doing e.g. mouse click event on page. Tried to use the accessSynchronously also. same problem. Changes appear only after 'touching' the screen.
no error/exceptions in console or logs.
Use from component that created using the @JavaScript annotation. working synchronously works fine, but when trying to be asych, seems that render stack somewhere. tried with Vaadin 24.10.1 and 24.3.3
Upvotes: 0
Views: 79
Reputation: 5766
When you want to modify the UI from an async Thread* using ui.access(() -> {...})
, then you need to have the @Push
notification on your View (or one of its "parent" routerLayout-views).
Otherwise that ui modification will show up only after your next server roundtrip (any user interaction in the UI -> button click, etc).
You can use @Push(PushMode.MANUAL)
if you intend to invoke ui.push()
after each call of ui.access(..)
.
Or you can simply use @Push
which will default to PushMode.AUTOMATIC - automatically pushing any changes that were made when the ui-lock from a ui.access(..)
call is lifted
Sidenote: Even though I mostly use automatic pushmode, it has occurred to me that I'd still need to call ui.push()
sometimes for it to work. I am not sure if that was a bug or an intentional edge-case.
* or within e.g. a click listener of a Button
if you want the modification to show before the whole clicklistener has completed (most common use case for me)
PS: you can simplify your code with a lambda expression:
current.access(() -> getElement().executeJs("this.widget.refresh(window.JSON.parse($0))", model));
Upvotes: 0