sialcasa / mvvmFX

an Application Framework for implementing the MVVM Pattern with JavaFX
Apache License 2.0
489 stars 104 forks source link

Strategy of creating sidebar and dynamic content views #535

Open CROSP opened 6 years ago

CROSP commented 6 years ago

Hi, thanks for a great library. I am hesitating to select a proper way of implementing a UI with a sidebar. It should look like the Google Analitcs WEB UI. So when you click on an option in the sidebar it changes only content view, but the sidebar, the header, the footer stay the same.

Could you please give any advice regarding this question considering MVVM approaches ? I would be grateful for any help

manuel-mauky commented 6 years ago

Hi, I think what you describe is called "routing" in the web-development world. There is a component called "router" that knows the current location/state of the app (in web apps defined by the URL) and it knows how to render specific URLs in the content area.

We don't have a special tool or API for this use-case yet. Maybe this would be a nice addtion to the framework but it's also not a simple task to implement because in desktop applications there is no such thing as a URL. So there needs to be some brain power put into planing this topic and an API.

In the mean time however, you could implement the use-case by yourself. You can load views based on some actions/conditions (like a button in your sidebar is pressed) and put the loaded view node into a content pane and replace existing nodes if any. In the first approach maybe this would result in relatively tight coupling between the action and the view-loading code but you could refactor and generify this afterwards. In my experience it's often easier to first build a naive approach and then refactore generic utils out of it. Sadly, I can't give you a precise example of such use case at the moment but I hope this still helps you for the moment.

CROSP commented 6 years ago

@lestard Thank you for the complete answer. I have tried to find any examples for routing in JavaFX and Mvvmfx powered applications, however haven't found any good examples on this matter.

Of course it is possible to implement this by changing content of some container dynamically. But I am looking for something called a "router", as you've already mentioned.

Generally, it would be great to implement some kind of routers hierarchy, to handle complex cases when we have multiple screens and each of them has nested routing logic.

Your framework, as well as JavaFX out of box, supports a lot of tools for dependency injection, binding, etc. I have experience of handling routing in different languages and frameworks, but I am quite a new person in the JavaFX world, therefore I don't know a whole tool set available for use.

The idea is to create some kind of an orchestrator module that will provide a convenient way for handling complex routing, hiding all details under the hood. A router object should be able to handle transitions between views, have a way to pass arguments between different views, without direct coupling.

A similar idea was described by the VIPER architecture

Maybe you have any ideas how to implement routing elegantly on the framework level to provide an easy way to handle transitions between views.

manuel-mauky commented 6 years ago

I don't have a good idea yet but I would be more then happy to add such a feature to the framework. It would definitely be in the scope of the project. However, I cannot guarantee to work on such a feature in the next time by myself. But if you like to start a trial on this I would love to give feedback and support.

Some thoughts on the router topic: I think it could be a very good idea to get inspired by routers from web frameworks. A lot of intelligent people have put work and brain-power into this topic so we should use that. On the other hand maybe not all concepts apply in desktop apps and in Java/JavaFX.

I think the first step should be to think about an API to define the location of the app. In web we have URI for this. Maybe we can use URIs here too. We should think about this. Things to keep in mind:

For this we would need a good API to create and work with URIs. Maybe there is something ready to use?

The next step is to think about how you define routes. In angular there is a static routing configuration. As a developer you configure which routes map to which components and where these routes are rendered (routing-target). On the other hand in react-router they use dynamic routing without an up-front-configuration. If at some point in your component-tree there is a route component that matches the current location then this route will render.

I personally like the dynamic approach of react-router but I think the static approach is more suited for JavaFX and desktop applications. So we would need to create an API to configure routes and mappings to components and to routing-targets. These route configurations need to be able to include sub-configurations defined in other packages to be modular.

The next step is to create a routing-target component for JavaFX. This component takes the configuration and renderes the defined components based on the current location.

And the last step is to create an API to change the current location. For example in react-router there is a Link component that changes the URI to a specified value. For JavaFX and mvvmFX we don't need a UI-Component but instead a Java API that can be invoked in the ViewModel.

As you can see there is a lot to do. In my experience it's best to first focus on API and only as a second step on the implementation. Having a good API that is easy to use is key in framework development. I can imagine to let a student of mine to work on this but it will definitely take a lot of time. On the other hand maybe you like to start working on this?