Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
CDI and custom components basic question
Hey guys, I'm new to vaadin and CDI but I am liking the combination a lot. I have a general question about crating custom components and the best practices to use them with CDI, hopefuly someone will understand it and be able to guide me :)
I won't be posting a lot of code example right now, as I don't think it will be necessary since the question isn't really complex. But if it eventually becomes necessary, i will create an example project.
Let's start then. I created a custom component (lets call it CC) that extends VerticalLayout and has a proprietary Service injected into it, but I didn't make CC's scope explicit yet (like @NormalViewScoped). In this component, I declared an init method (not a @PostConstruct) which receives a pojo as parameter and populates its fields.
After this, i declared a CDIView that has a TabSheet. It starts with one tab, which will have a table on it, populated by the same type of pojo as before. I added a clicklistener to the table so that once someone clicks on one of the items it does the following:
- Checks if a Tab with caption equals to the pojo's name attribute already exists in the TabSheet.
- If it does, set such tab as selected.
- If it doesn't, then it creates a CC, calls its init method with the clicked pojo, and adds CC as a new tab with the pojo name as caption.
Before utilizing cdi, I would simply call new CC() and then init(pojo). However, now i am Injecting something into CC, therefore i can't actually call new, otherwise the injection will not work. I thought of injecting CC into the CDIVIew, but it would only be one attribute which would have its fields overwritten, whereas what i actually need is always a new instance of CC to be added to the tabsheet.
Is there an elegant way to solve this with vaadin and cdi? The approach i had to take was the following:
I created a class that handles CC production, CCProducer. I injected the service into it and created a getCC method, that:
- Receives the pojo as param
- Creates a new CC (removed injection from it, went back to using new CC() )
- Initializes the CC with the POJO
- Sets the new CC service with the producer's injected service
- Returns CC
Then i injected this new producer class to my cdi view, and where i would create the new tabs i replaced the calls for the producer's getCC method.
The problem i see with this approach, is that if i ever want to add something to CC, like say a button that opens a custom window with injected stuff, I won't be able to inject the window to it and etc, because CC went back to being a non JEE class..
You can inject an Instance of your CC, like this:
@Inject Instance<CC> myCC;
Then, when you need a new instance of the CC, do this:
Hope this helps!
Only had time to test it now, but using Instance<> solved everything i needed and more. Thank you so much for the reply :)