Open basil-bourque opened 5 years ago
I found yet another need for this suggested HasAttributes
interface: Consistency.
The VaadinSession
class offers pairs of both setAttribute
and getAttribute
methods. Each is overloaded to take either a Class
object or a String
object as the key.
In contrast, the VaadinContext
class has only a single setAttribute
and getAttribute
. Each takes only a Class
as the key, with no option to use a String
name as the key. This commission seems silly. Why not give the Vaadin-using programmer a way to store state conveniently by choice of either a Class
or String
key?
I'm in favor of adding something for supporting these use cases, but I have to admit I'm unsure of the suggested API of attributes
since it collides a bit with the client side Element API attribute (for me). For Session it is part of the spec to have it as attribute though, so maybe it would be clear that this is for the same thing on the server side state for Component
? But I still wonder if someone would also expect that the data would be sent to the client also and made available there.
The same thing was kind of in V7 and V8 available with the setData
API for Component
. We felt that the API was named "badly" and was much misused to workaround all kinds of cases where the framework lacked a proper feature. That is why I would hope to know the concrete use cases that one would wish to achieve with this feature.
Once we have concrete examples, it should be quite straight forward for us to come up with an adequate design and then have this ready to go for development team or for external contributions to get it into the framework.
The
VaadinSession
andVaadinContext
classes both offer the ability to store state used during execution of our Vaadin web app. Both classes offer a key-value store of attributes, with methodssetAttribute
,getAttribute
, andremoveAttribute
. This feature is quite handy as a place for Vaadin-using programmers to store session-scope state and context-scope state.I suggest formalizing that behavior as a "mixin" interface named "HasAttributes". Retroactively define the two classes named above as implementing
HasAttributes
.➥ More importantly, implement
HasAttributes
on theComponent
class.As the superclass of both layouts and widgets, giving the
Component
class the ability to store arbitrary bits of state useful to a particular Vaadin-using app developer would be very handy, even vital in some scenarios.The need might be as simple as storing some user-preference/setting local to a layout or other grouping of widgets.
Another use-case would be storing state per web browser window/tab, given that Vaadin enables multi-window apps. In Vaadin 8 era, the
UI
class provided this per-window/tab scope. In our subclass ofUI
, we could define our own variables or even our own key-value collection with aMap
. But now in Vaadin Flow, we are not usually writing aUI
subclass. Even if we tried, the new architecture of Vaadin Flow has intentionally made aUI
instance replaceable with another, for example, when user clicks the browser Reload button — therefore, we cannot practically store useful state there as the instance can disappear at any moment. So now, in practice, for many of us building Vaadin Flow apps, ourMainView
class becomes the shell of our app, the container for all the content within a web browser window/tab. So thatMainView
takes the place of the oldUI
as representing the per window/tab scope of our app. As a layout, and therefore aComponent
, giving anyMainView
class the built-in capability to store and retrieve attributes as a key-value store would be quite handy.A more exotic use-case might be when the Vaadin app is being built from generated code, or built as part of another framework. In my own work, I am building a translation tool to port apps from an old GUI framework and application development environment to Vaadin & Java. I am programmatically re-creating the views of the old app architecture as Vaadin layouts and widgets. So being able to store some state within my Vaadin layouts and widgets to tie them back to their legacy counterparts could be very useful.
The workaround would be the Vaadin-using programmer adding their own key-value collection management. Perhaps the various layouts or widgets could be extended in subclasses for this purpose by us Vaadin-using programmers. But given that Java lacks the ability to add methods to existing classes (such as Category in Objective-C), we would have to be writing many such subclasses. It makes more sense to have this behavior built into Vaadin itself.
As for performance and overhead impact, there not need be much impact. The underlying implementation of the key-value store is probably going to be a
Map
such asHashMap
. That map object could be lazily instantiated, creating a new map only upon the first call tosetAttribute
for a particularComponent
instance.