Reputation: 41
After navigating to a new view i want to start a background thread, which does some validation and reports changes to my view. I am building the ui and starting the thread on AfterNavigationObserver#afterNavigation
.
Most of the time this works, but when the background thread finishes too fast it can't update the view cause the rendering is not finished and the component to update is not visible yet. The possible solution would be to start the background thread after the rendering is finished and the view is visible in the browser. What is the recommended way to do this? I looked through the APIs but can't find a matching event.
Using vaadin-flow 14.8.
In the following minimal example the second accordion panel should be opened when the task finished. It works on my pc mostly with a timeout of 500 ms or greater. Going below this value or removing the sleep results in not opening the second accordion.
The view:
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.accordion.Accordion;
import com.vaadin.flow.component.accordion.AccordionPanel;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.page.Push;
import com.vaadin.flow.router.AfterNavigationEvent;
import com.vaadin.flow.router.AfterNavigationObserver;
import com.vaadin.flow.router.Route;
import de.fs_aut.ddm.desktop.bgtasks.TimeConsumingTask;
import org.springframework.beans.factory.annotation.Autowired;
@Route("debug")
@Push
public class DebugView extends VerticalLayout implements AfterNavigationObserver {
@Autowired
private TimeConsumingTask task;
private UI ui;
private Accordion acc;
private AccordionPanel firstPanel;
private AccordionPanel secondPanel;
@Override
public void afterNavigation(AfterNavigationEvent event) {
removeAll();
acc = new Accordion();
firstPanel = new AccordionPanel("First task", new Label("first task in progress"));
secondPanel = new AccordionPanel("second task", new Label("second task in progress"));
acc.add(firstPanel);
acc.add(secondPanel);
add(acc);
startValidation();
}
public void startValidation() {
ui = UI.getCurrent();
task.sleep().addCallback(result -> {
ui.access(() -> {
acc.open(secondPanel);
});
}, error -> {
});
}
}
The async task:
import java.time.LocalDateTime;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.util.concurrent.ListenableFuture;
/**
* Testdummy. Does nothing but waits.
*
*/
@Service
public class TimeConsumingTask {
@Async
public ListenableFuture<String> sleep() {
try {
Thread.sleep(500);
} catch (final InterruptedException e) {
e.printStackTrace();
}
return AsyncResult.forValue("Validation finished at " + LocalDateTime.now().toString());
}
}
Upvotes: 1
Views: 678
Reputation: 1645
Knoobie's answer should be checked, but (if I remember correctly) StackOverflow guidelines prefers code over a link to the same.
Every Component
the onAttach(DetachEvent)
method. From the Javadoc:
`protected void onAttach(AttachEvent attachEvent)
Called when the component is attached to a UI.
The default implementation does nothing.
This method is invoked before the AttachEvent is fired for the component.
Parameters:
attachEvent - the attach event
You can override this method in any Component
:
public class MyComponent extends VerticalLayout {
@Override
protected void onAttach(AttachEvent event) {
System.out.println("I attached: " + event);
}
}
Component
also implements AttachNotifier
, which offers the this method:
public class MyComponent extends VerticalLayout {
public MyComponent() {
addAttachListener(event -> System.out.println("I attached: " + event));
}
}
Note the docs quoted above! The onAttach
method is called before the event.
Another approach is from JavaScript to wait for the v-loading-indicator
's first child to have display: none
.
Upvotes: 0
Reputation: 2064
You could try to overwrite and implement onAttach on your route. See https://vaadin.com/docs/v14/flow/creating-components/tutorial-component-lifecycle-callbacks for more details.
Upvotes: 1