Im curios about this. I have for example this code :
button_article.addClickListener(new ClickListener(){
public void onClick(Widget w) {
GWT.runAsync(new RunAsyncCallback() {
public void onFailure(Throwable reason) {
// somethings
}
public void onSuccess() {
content.clear();
content.designArticles();
}
});
}
});
public final void designArticles() {
this.add(new ProfileArticles(this.rpcService, this));
}
I see that until i click on button_article, the elements on ProfileArticles() (that is a FlowPanel) arent loaded when i start the application. So, how can GWT know that element on that class shouldnt loaded when the application start? It check each methods under GWT.runAsync() and their correspondents Class?
I also see that when i leave that "context" they arent released (in fact, if i change context and i return there, when i click again on that method it doesnt call the server. So it use the previous loaded code). Is it right? :)
Cheers
The GWT compiler analyzes the flow of your program to figure out what chunks it can load later. If you want to visually understand what it's done, check out http://code.google.com/webtoolkit/doc/latest/DevGuideCompileReport.html .
Once code is loaded, most of it can be cached, so even if the user navigates off the page and then back to yours, the code will not need to be reloaded.
Related
I have a org.apache.wicket.markup.html.panel.FeedbackPanel in my panelA class. The feedback panel is instantiated in a panelA constructor with one message to display -> feedbackPanel.info("displayFirstTime"). I am navigating to a new page and later to the previous panelA with a command
target.getPage().get(BasePage.CONTENT_PANEL_ID).replaceWith(panelA);
but the message "displayFirstTime" won't be displayed on the feedback panel again.
I have made it with overriding a panel onBeforeRender method
#Override
public void onBeforeRender() {
super.onBeforeRender();
if (again_displayCondition) {
this.info("displayFirstTime");
}
}
but it's not a clean solution.
Is it possible or how to make it, that when moving to a panelA page for the 2nd time the feedback message will be also displayed ?
Wicket uses application.getApplicationSettings().getFeedbackMessageCleanupFilter() to delete the feedback messages at the end of the request cycle.
By default it will delete all already rendered messages.
You can setup a custom cleanup filter that may leave some of the messages, e.g. if they implement some interface. For example:
component.info(new DoNotDeleteMe("The actual message here."));
and your filter will have to check:
#Override
public boolean accept(FeedbackMessage message)
{
if (message.getMessage() instanceOf DoNotDeleteMe) {
return false;
}
return message.isRendered();
}
Make sure you implement DoNotDeleteMe#toString() so that it renders properly. Or you will have to use a custom FeedbackPanel too.
DoNotDeleteMe must implement java.io.Serializable!
I'm changing the sites locale with an AjaxLink:
#Override
public void onClick(AjaxRequestTarget target) {
Session.get().setLocale(newLanguage.getLocale());
// Add whole page to update instead of single components
target.add(getPage());
}
It does work as i expect, every i18n string on the entire page gets updated while form contents are kept. Splendid.
But testing with WicketTester won't work out. Both methods, clickLink and executeAjaxBehavior, do trigger the AjaxLink, but WicketTester doesn't detect any changes for the model value.
#Test
public void check() {
tester.startPage(SwitchLangPage.class);
tester.clickLink("link", true);
tester.assertModelValue("link:label", "English");
}
Am I missing something importent here?
(Wicket 6.19)
Edit: Gist with a simplified panel
Ok, I am very confused about "onBind", "preparedFromRequest", "onReveal", "onReset" in GWTP. I don't know When & in Which circumstance these methods were called.
Ok, i got Page1Presenter.java (tokenName: page1) has the following codes:
#Override
protected void onBind(){
System.out.println("on bind");
}
#Override
protected void prepareFromRequest(PlaceRequest request){
System.out.println("prepared from request");
}
#Override
protected void onReveal(){
System.out.println("on reveal");
}
#Override
protected void onReset(){
System.out.println("on reset");
}
Now, i open page1 in browser, url: abc.com/#page1;param=1, then it prints out:
on bind
prepared from request
on reveal
on reset
Then, I go to abc.com/#page2 & then press back button, now it prints out:
prepared from request
on reset
Then, change param & enter abc.com/#page1;param=2, it will show:
prepared from request
on reset
Then, i click other browser tab & click back to the tab containing the url abc.com/#page1;param=2, then nothing happened. I expect onReveal will be called.
Also, System.out.println(); is too simple so we can't see the difference between preparedFromRequest & onReset.
If we have a lot of complicated code & if we put that code in preparedFromRequest, will it behave differently if putting into onReset?
& Do they behave the same in different browsers?
This short description on GWTP Presenter Lifecycle answers most part of your question.
I'm trying to do the following:
I want to add a specific handler for some links, denoted by a class.
$("a.link_list").live("click", new ListLinkHandler());
I need .live() instead of .bind() because new such links will be generated. (I know jQuery's .live() is deprecated in favor of .on(), but gwt-query doesn't have a .on() yet.)
I defined the handler like this (just as the gwtquery example does):
public class ListLinkHandler extends Function {
#Override
public boolean f(Event e) { [...] }
}
However, the handler method is never called when I click the links.
I can see the event listener in Chrome Dev Tools: http://screencloud.net/v/bV5V. I think it's on the body because it's a .live().
I tried using .bind() and it worked fine. The body event listener changed in a a.link_list and the handler does what it's supposed to do, but (as documented, I didn't test) not for newly created links.
I filed a bug for the .live() method, but maybe I'm doing something wrong.
Also, I have no idea how to do it without gwtquery, GWT doesn't seem to have a method for selecting elements by class, neither to continually add the listener to new elements.
It seems you are doing something wrong, but I need more code to be sure. Could you send the complete onModuleLoad code which demonstrates this wrong behavior?
I have written a quick example using live, and it works either when adding new gwt widgets or dom elements with gquery, in both Chrome and FF
public void onModuleLoad() {
$("a.link_list").live("click", new ListLinkHandler());
// Add a new link via gquery
$("<a class='link_list' href=javascript:alert('href') onClick=alert('onClick')>Click </a>").appendTo(document);
// Add a new link via gwt widgets
Anchor a = new Anchor("click");
a.setStyleName("link_list");
a.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
Window.alert("clickHandler");
}
});
RootPanel.get().add(a);
}
public class ListLinkHandler extends Function {
#Override
public boolean f(Event e) {
Window.alert("live");
return true;
}
}
I have added some extra functionality to the standard GWT ListBox by extending it like so:
public class FeatureListBox extends ListBox
{
public FeatureListBox()
{
}
public FeatureListBox(boolean isMultipleSelect)
{
super(isMultipleSelect);
}
public FeatureListBox(Element element)
{
super(element);
}
}
Nothing fancy here. However, the Change event is not firing now, or at least the handler (attached per below) is not getting invoked.
FeatureListBox listBox = new FeatureListBox();
listBox.addChangeHandler(new ChangeHandler()
{
public void onChange(ChangeEvent event)
{
// Do something here...
}
});
Any ideas why?
Either remove the no-argument constructor from FeatureListBox or call super() inside it, otherwise the initialization in the superclasses won't happen, which would probably result in what you're seeing.
The problem was in the way I was using my custom list box. In my application I wrap GWT Widgets around existing DOM elements on the page using the static wrap() methods of their widget classes in which the widgets get marked as attached, making them fire events. I didn't do that with my custom list box class originally, so I ended up implementing a static wrap() method similar to the one of the regular ListBox widget and using it in my code. Everything works like a charm now.