Closed Patrick1701 closed 9 years ago
Hi Patrick, I am (unfortunatly? :p) in vacation and have absolutely no chance to look at this before I return... Best regards! Sebastien
Hi Sebastien, no problem... using my detach() trick for now.
Enjoy your vacations, have fun! :-) Patrick
Hi Patrick,
As you figured out, ITab
(s) should be Serializable
for the reason they should keep their state (init, etc), so you cannot use a LDM...
I think you can easily correct this by using WildcardListModel
(and I am wondering if it wasn't the sense of your separate mail's title ! ;) )
Hope this helps & thanks to close the issue if it's ok for you...
Best regards, Sebastien.
and I am wondering if it wasn't the sense of your separate mail's title ! ;) )
Ooohhh.... lol... :) ähm, no. Funny... Now I understand why you have seen my mail as "push to work"-request. The abbreviation WM was in german by mistake... and was meant for "World Cup" / "W_elt_M_eisterschaft". The sense of the "Sorry!" also... ;-P
(My attention was not to put pressure of your working load, immediatly after your vacations.)
... Ok, I will have a look to the WildCardListModel.
Thanx :-) Patrick
Hi Patrick, To be honest, I didn't felt too much pressure (or less than a certain football team in a certain time) ;)
Best regards, Sebastien.
:-D
Ok, the WildCardListModel makes it easier to handle and implement a List Model... but the loading issue is still there.
getObject() of WildcardListModel is called multiple times, not only twice.
Overriding detach() of my WildCardListModel, like in my LDM hack (doing nothing / no detach), does not work here. Will keep my LDM hack for now.
So, using a model to provide the tabs still seems to be quite tricky, right now.
Patrick
Well, I am a little bit surprised because the List should not be detached (not an instance of IDetachable
). And it should also not be reloaded because it is not a LDM. But if you overrided #getObject
to load the List each time, well that's a design issue. IMO, get the list, pass it to the WLModel object and - if I undertand the usecase correctly - it should be ok...
static class TabListModel extends WildcardListModel<ITab>
{
public TabListModel()
{
// load list //
List<? extends ITab> list = Arrays.asList(new SimpleTab("title", "content"));
this.setObject(list);
}
}
public MyPage()
{
final AccordionPanel accordion = new AccordionPanel("accordion", new TabListModel(), options);
}
Me, too... I've seen the if(IDetachable)... in wickets code. I will give it a try, again. Maybe I did something wrong.
But, concerning your example: The tabs in my case are very dynamically depending of my database state. Thats why I want to use a Model, loading it on render-time and not on construction-time of my class. And I also have to unpack another model first, to fetch my data for the tabs. This is what I want to avoid in my constructors by using a model.
Possibly, using a LDM with a detach() -> doing nothing, is the best way here. May I have to change my point of view, not to see this as an hack. Hmm...
IMO, the problem I see with LDM is that the backing model object is transient, so it is not supposed to be serialized/reused from one request cycle to another. I think the best is to write your own model, extended from WLM, with a loading logic inspired from LDM (transient 'attached' flag). While reloading db-tabs, you have to compare with the existing tab list, adding missing ones and removing old ones. The commons tabs should be kept to keep their state. Just thoughts...
Ok, I see the LDM problem now as well... hmm... then I'm wondering why its working. lol The two calls, I mentioned above, must be in the same RequestCycle then, right?
Let me bring some light!
By default Wicket stores the last used live page in the http session, and its serialized view in the disk. On the next request (e.g. a click on a Link) Wicket will first search in the http session and if there is no match then in the disk. So it is possible to use non-serialized page (but detached!) between several requests. Read https://cwiki.apache.org/confluence/display/WICKET/Page+Storage for more details.
I haven't read the earlier comments here so I'm not sure whether my answer explains a cause or not.
Hi Martin, thanks for the enlightenment! I guess the question here is more on how to have a dynamic model which reloads on each request but keep track of previous -serialized- model object (implementation should perform a kind of merge between old and new items).
Patrick, right, the 2 calls are in the same request. #Detach occurs at the end of the request...
Hi Martin, thanx a lot, too.
Could you please enlight my WildCardListModel problem, as well? Do you have an idea, why it is not working in my case?
getObject() of WildcardListModel is called multiple times...
I expected only one getObject() call, not many.
kind regards Patrick
Hi Patrick,
Did you finally found an acceptable solution?
FYI, #getObject()
can be called as many time as needed, there is no contract about this (as opposed to LDM#load
for instance).
I will close this issue as I think there is nothing to do on my side. If you do not agree, you can reopen it. If you have still questions on this topic, feel free to open a discussion in the forum.
Thanks for your understanding & best regards, Sebastien
Hi Sebastien, I think I will leave it as it is.
The code is very local, the overriding detach() "doing nothing" is easy to understand, I commented it, and added a link to this discussion/issue. No one here should get huge problems with my code.
Thanx a lot Patrick
Hi Sebastien, happy new year! :-)
I'm working again on TabbedPanels which dynamically create tabs depending on some other components on a page and database data, I still run into this issue we discussed in this thread.
After several implementations of this TabbedPanel I've done the last months which uses LDMs, I more and more think about the wish to have a more non-static version of this Component.
As far as I can see, the Tabs are quite "static" due to the fact, they are added to the internal ListView in onInitialize()
of TabbedPanel
.
So, its it possible to fetch tabs from a model, but only once the TabbedPanel is created, but never again in its Lifecycle.
I can manipulate Tabs by using add(ITab)
... this is helpfull for an "add tab"-use-case but, not for fetching them modeled from a database.
Additionally to my hack above, not to detach my TabList-LDM, I force a re-initialized TabbedPanel by using another workaround (lifecycle-break):
onSomething(AjaxRequestTarget target){
surroundingContainer.addOrReplace(new TabbedPanel("p", LDM-for-tabs, new Options()));
target.add(surroundingContainer);
}
instead of just
onSomething(AjaxRequestTarget target){
target.add(tabbedPanel);//(does not re-render tabs right now)
}
I'm not sure if I request some sort of non-natural feature/behavior for TabbedPanels, but I have this situation quite often.
Possibly adding the tabs in onBeforeRender()
, not in onInitialize()
could achive this, but I'm not sure.
What do you think?
best regards Patrick
Hi Patrick,
Thank you very much, happy new year to you too! :)
ITab
(s) are static for the reason they should keep their state (that's the reason not using a LDM). I can try to study how we can have a dynamic model... I just will ask you a little bit of more patience, everything will go back to a normal situation by the end of the month (crossing fingers)...
Thanks & best regards, Sebastien.
I just will ask you a little bit of more patience, everything will go back to a normal situation by the end of the month (crossing fingers)...
Ok, good luck! :-)
( I hope you don't feel bothered, when I go on opening further issues... ;-) )
best regards Patrick
I hope you don't feel bothered, when I go on opening further issues...
I won't feel bothered, I will feel sorry! :)
I will try to spend time on this this week-end, sorry for the delay! :)
Hi Patrick,
I can try to study how we can have a dynamic model...
So, I've added a TabListModel
, which is a loadable (non detachable) model. You can use it for your dynamic List<ITab>
which contains AjaxTab(s)
.
Please note: in order to refresh the Accordion
(and reload the model), please use AccordionPanel#refresh
(instead of target.add(accordion)
). If you cannot refresh the Accordion
directly, call myTabListModel.flush();
then target.add(myAccordionContainer)
Deployed 6.19.2-SNAPSHOT
Best regards, Sebastien,
Ok, I will check that next, when I am upgrading...
Thanx a lot. Patrick
Hi Sebastien, works great!
kind regards :-) Patrick
Hi Sebastien, I implemented an Accordion using the Accordion-constructor for IModel<List<? extends ITab>> and give a LoadableDetachableModel implementation to provide AjaxTabs.
The detaching-feature of the LDM, let the Accordion call getObject() twice. The first on AccordionPanel#onInitialize() and the second later on Ajax-Create-event of the AccordionBehavior.
Due to that, the ITabs loading state doesnt match anymore (caused by another "new" tab instance), and the first AjaxTab never get loaded, because it is still in INIT_STATE.
Overriding detach() of my LDM, doing nothing, can fix this.
After this I tried to implement a BasicModel/Model not to have detaching-logic, but I did not get this compiled because the Model-generic type must be T extends Serializable, and the constructor of AccordionPanel only provides IModel<List<? extends ITab>>. I wasn't able to implement a serializable list of ITabs. Also tried ListModel... but I did not get it compiled.
Is there any trick?
Back to the LDM... is this a bug? Or just a javadoc issue?
kind regards Patrick