Wicket – verzögerte Initialisierung | wicket praxis
Skip to content


Wicket – verzögerte Initialisierung

Nicht immer ist es möglich oder sinnvoll, im Konstruktor einer Komponente bereits die vollständige Komponentenstruktur anzulegen. Wie man Komponenten zu einem späteren Zeitpunkt anlegen kann, kann man in den Repeater-Klassen ansehen. Aber es geht wesentlich einfacher. Nach dem Erstellen einer Komponente wird als nächstes (für den Fall,dass die Komponente dargestellt wird) onBeforeRender() aufgerufen. Wir können die fehlenden Komponenten in diesem Methodenaufruf erstellen. Wir müssen nur darauf achten, dass diese Initialisierung nur einmal durchgeführt wird. Am besten verpacken wir das ganze in eine eigene Klasse.

 Java(TM) 2 Platform Standard Edition 5.0 | 
 
 copy code |
?

  1. package de.wicketpraxis.web.blog.pages.questions.lazy;
  2. import org.apache.wicket.markup.html.panel.Panel;
  3. public abstract class AbstractLazyPanel extends Panel
  4. {
  5.   boolean _lazyInitCalled;
  6.   
  7.   public AbstractLazyPanel(String id)
  8.   {
  9.     super(id);
  10.   }
  11.   @Override
  12.   protected void onBeforeRender()
  13.   {
  14.     if (!_lazyInitCalled)
  15.     {
  16.       _lazyInitCalled=true;
  17.       lazyInit();
  18.     }
  19.     super.onBeforeRender();
  20.   }
  21.   protected abstract void lazyInit();
  22. }

Eigene Komponenten werden dann von dieser Klasse abgeleitet. Dieser Umbau hat keine Veränderung des Markup zur Folge, da keinerlei Hilfskomponenten eingefügt wurden.

 Java(TM) 2 Platform Standard Edition 5.0 | 
 
 copy code |
?

  1. package de.wicketpraxis.web.blog.pages.questions.lazy;
  2. import org.apache.wicket.markup.html.basic.Label;
  3. import org.apache.wicket.model.Model;
  4. public class TestPanel extends AbstractLazyPanel
  5. {
  6.   public TestPanel(String id)
  7.   {
  8.     super(id);
  9.   }
  10.   @Override
  11.   protected void lazyInit()
  12.   {
  13.     add(new Label("label",Model.of("Label")));
  14.     add(new SimplePanel("panel"));
  15.   }
  16. }

 HTML | 
 
 copy code |
?

  1. <wicket:panel>
  2.   <span wicket:id="label"></span>
  3.   <br>
  4.   <wicket:container wicket:id="panel"></wicket:container>
  5. </wicket:panel>

Wie man sieht, lässt sich die neuen Klasse sehr einfach als Ersatz für die Panel-Klasse benutzen. Vielleicht ist dieser Ansatz ausbaufähig, so dass man durch eine verspätete Initialisierung auch die Probleme rund um TransparentResolver umgehen kann.

Posted in Allgemein, Refactoring, Wicket.

Tagged with , , , .


8 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Nick Wiedenbrueck says

    Interessanter Beitrag. Wir benutzen diese Methode häufiger.

    > Wir müssen nur darauf achten, dass diese Initialisierung nur einmal durchgeführt wird
    Als Variante kann man in onBeforeRender() auch zunächst alle Kind-Komponenten entfernen (removeAll()) und danach wieder neu erzeugen lassen, so dass die Kind-Komponenten bei jedem Rendern neu erzeugt werden. Dadurch erhält man quasi ein „AbstractRefreshingPanel“, analog zu einer RefreshingView.

  2. Martin says

    Man sollte den if noch ein synchronized spendieren:

    synchronized (this) {
    if (!_lazyInitCalled)
    {
    _lazyInitCalled=true;
    lazyInit();
    }
    super.onBeforeRender();
    }

  3. Ilja Pavkovic says

    das liefert wicket alleine:

    public void onBeforeRender() {
    if(!hasBeenRendered()) {
    // initialize
    }
    super.onBeforeRender();
    }

    • michael says

      AFAIK werden die Komponenten dann aber erst initialisiert, wenn die Elternkomponente auch sichtbar ist…. aber sonst, ja, geht auch so.

      • Ilja Pavkovic says

        will man das denn vorher?

        • michael says

          Es ist nicht auszuschließen.. wenn man z.B. über Events auch unsichtbare Komponenten erreichen möchte.. in der Palette-Komponente (wicket extensions) gab es mal einen Bug, der auf so eine Problemstellung zurückzuführen war..

          • Ilja Pavkovic says

            das stimmt.

            Ich habe mir den sourcecode von Component noch mal näher angeschaut und glaube, dass man sich doch nicht auf hasBeenRendered verlassen sollte, das der Zustandswechsel dort von vielen Randbedingungen abhängt.

Continuing the Discussion

  1. Tweets die Wicket – verzögerte Initialisierung | wicket praxis erwähnt -- Topsy.com linked to this post on 20. Januar 2010

    […] Dieser Eintrag wurde auf Twitter von Nick Wiedenbrueck, mosmann erwähnt. mosmann sagte: New blog post: Wicket – verzögerte Initialisierung http://www.wicket-praxis.de/blog/2010/01/20/wicket-lazy-init/ […]



Some HTML is OK

or, reply to this post via trackback.