question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add a method to find the active view (or parent view/layout)

See original GitHub issue

Describe your motivation

When building re-usable components they often need to interact with other parts of the UI, like the current view, navigation menu or some shared parts in some parent layout. Those are most often components in the current component tree, but in Vaadin provides no easy way to search them up. Instead we then inject them to other components using Spring/CDI or build application specific hacks to get references to them.

Providing a way for developers to seek views from the active UI might make it easier to create re-usable code.

Describe the solution you’d like

A code example of a method (that could be placed to the UI class with minor changes):

    /**
     * Finds a reference to the current view or parent layout of given type.
     * 
     * @param viewType the class of the view or parent layout to search for
     * @return the view or empty optional if given view is not active
     * @param <T> the type of the view or parent layout to look for
     */
    public <T extends Component> Optional<T> findView(Class<T> viewType) {
        List<HasElement> activeRouterTargetsChain = UI.getCurrent().getInternals().getActiveRouterTargetsChain();
        for (HasElement element : activeRouterTargetsChain) {
            if (viewType.isAssignableFrom(element.getClass())) {
                return Optional.of((T) element);
            }
        }
        return Optional.empty();
   }

The implementation would be pretty much the same as in a private helper introduced in https://github.com/vaadin/flow/pull/13906

Then e.g. a single component could call a method in main layout like this:

ui.findView(MainLayout.class).ifPresent( main -> main.makeNewMessagesIndicatorBlink());

Describe alternatives you’ve considered

Write all code into single class and all problems are solved 🤓

Alternatively, Component could have a following helper:

/**
 * Finds a parent component of given type.
 *
 * @param componentType the class of the component to search for
 * @return the component
 * @param <T> the type of the component
 */
public <T extends Component> T findParent(Class<T> componentType) {
    Optional<Component> parent = getParent(); // see, parent here is Optional as well :-)
    while (parent.isPresent()) {
        Component component = parent.get();
        if (componentType.isAssignableFrom(component.getClass())) {
            return (T) component; // or Optional.of((T) element);
        } else {
            parent = component.getParent();
        }
    }
    return null; // or Optional.empty() or throw
}

Additional context

I have been missing this kind of functionality in my own apps couple of time, but got the idea to bake this into actual proposal while working on improving the routing & navigation docs related to https://github.com/vaadin/flow/pull/13906 & https://github.com/vaadin/docs/issues/1482

Issue Analytics

  • State:closed
  • Created a year ago
  • Reactions:4
  • Comments:8 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
mstahvcommented, Jun 16, 2022

I talk about views all the time. For me “route maps the view to a certain URL” or “route is a view that is mapped to a certain url”. I had a findRoute originally as the method name, but then again, that is also returning “parent layouts”. Some of them define parts of the url/route, but not all. But I’d bet with both versions people could find it.

And yeah, the verb should be get if not returning Optional. My spine reads null checks better than Optional clauses, so I’m not a big fan of Optional either. On the other hand, we have already spoiled the framework with Optional usage, so I don’t have strong opinions on its usages. The @vaadin/flow team decides and my guess is what I had in the draft.

I wonder how common it is to search for views/routes from siblings/children 🤔 If not there could be an alternative solution for the very same problem, that might be even more helpful (would not just find views (or routes and their parent layouts)). The following method could be added to the Component class, so we could also get rid of one dance to get the UI reference (with UI.getCurrent() or Optionals that we all love 😂) :

/**
 * Finds a parent component of given type.
 *
 * @param componentType the class of the component to search for
 * @return the component
 * @param <T> the type of the component
 */
public <T extends Component> T findParent(Class<T> componentType) {
    Optional<Component> parent = getParent(); // see, parent here is Optional as well :-)
    while (parent.isPresent()) {
        Component component = parent.get();
        if (componentType.isAssignableFrom(component.getClass())) {
            return (T) component; // or Optional.of((T) element);
        } else {
            parent = component.getParent();
        }
    }
    return null; // or Optional.empty() or throw
}
0reactions
vaadin-botcommented, Sep 7, 2022

This ticket/PR has been released with Vaadin 23.2.0.

Read more comments on GitHub >

github_iconTop Results From Across the Web

android - get parent's view from a layout - Stack Overflow
The getParent method returns a ViewParent , not a View . You need to cast the first call to getParent() also: RelativeLayout r ......
Read more >
View - Android Developers
These dimensions define how big a view wants to be within its parent (see Layout for more details.) The measured dimensions can be...
Read more >
Displaying and managing views with a view controller
Add views to your view controller ... UIViewController contains a content view, accessible from the view property, which serves as the root view...
Read more >
About Controlling Callout Visibility | Revit 2022
Show in. When a callout view is associated with a parent view, the Show in view parameter can be set to Intersecting Views...
Read more >
Create a form that contains a subform (a one-to-many form)
For example, if you are working on a form in Layout view or Design view and you drag a table or query from...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found