Hello everyone,
I have an issue with refreshing a DetailView in our application and hope you can help me out.
We have Customer and Order entities, and in the Customer DetailView, we display the total amount of all orders. When a new order is created and the Order DetailView is closed, the Customer DetailView should automatically refresh so that the total amount is recalculated and displayed without having to close and reopen the entire view.
Here is a snippet of my code:
package com.company.jedr.view.customer;
import com.company.jedr.entity.Customer;
import com.company.jedr.entity.Order;
import com.company.jedr.view.main.MainView;
import com.vaadin.flow.component.AttachEvent;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.router.RouteParameters;
import io.jmix.flowui.ViewNavigators;
import io.jmix.flowui.view.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
@Route(value = "customers/:id", layout = MainView.class)
@ViewController("Customer.detail")
@ViewDescriptor("customer-detail-view.xml")
@EditedEntityContainer("customerDc")
public class CustomerDetailView extends StandardDetailView<Customer> {
private static final Logger log = LoggerFactory.getLogger(CustomerDetailView.class);
@ViewComponent
private Span totalAmountSpan;
@Autowired
private ViewNavigators viewNavigators;
@Subscribe
public void onAttachEvent(final AttachEvent event) {
if (CollectionUtils.isEmpty(getEditedEntity().getOrders())) {
return;
}
getEditedEntity().getOrders().stream()
.map(Order::getAmount).reduce(Double::sum)
.ifPresent(totalAmount -> totalAmountSpan.setText("Total amount: " + totalAmount));
}
@Install(to = "ordersDataGrid.create", subject = "afterSaveHandler")
private void ordersDataGridCreateAfterSaveHandler(final Order order) {
closeWithSave()
.then(() -> viewNavigators.detailView(Customer.class)
.withViewClass(CustomerDetailView.class)
.withRouteParameters(new RouteParameters("id", getEditedEntity().getId().toString()))
.navigate()
);
}
@Subscribe
public void onAfterClose(final AfterCloseEvent event) {
log.info("Close Event: " + event.getCloseAction());
}
}
My problem is that during the first refresh, a blink effect occurs, which works but is not ideal. When trying to add another order, the refresh does not happen, and there is no blink effect anymore.
The logs show different orders of the close actions being fired:
2024-06-11T17:23:52.406+02:00 INFO 91833 --- [nio-8080-exec-3] c.c.j.view.customer.CustomerDetailView : Close Event: CloseAction{actionId='save'}
2024-06-11T17:25:06.117+02:00 INFO 91833 --- [nio-8080-exec-3] c.c.j.view.customer.CustomerDetailView : Close Event: CloseAction{actionId='save'}
2024-06-11T17:25:06.145+02:00 INFO 91833 --- [nio-8080-exec-1] c.c.j.view.customer.CustomerDetailView : Close Event: CloseAction{actionId='navigate'}
Perhaps as a more general question: what would you suggest for re-rendering the UI of a detail view after some interaction happend. Re-rendering could mean something like:
- statically calculated values that are not two-way data-bound
- refresh the visibility / enabled settings of buttons
Thanks
Mario