2012-03-12 13 views
5

Próbuję zaimplementować Breadcrumb Navigation na WebPage, która wymienia zawartość Panel przez ajax.Etykieta wicket nie jest aktualizowana/pozostaje niewidoczna

kończy się wyglądać jak ten: Home >> Page >> Panel

Oto mój kod strony:

public MyPage() { 
    super(); 
    contentContainer = new WebMarkupContainer("contentContainer"); 
    contentContainer.setOutputMarkupId(true); 
    add(contentContainer); 
    contentContainer.add(content = createContentPanel()); 

    breadCrumbContainer = new WebMarkupContainer("breadcrumbContainer"); 
    breadCrumbContainer.setOutputMarkupId(true); 
    add(breadCrumbContainer); 

    final AjaxLink panelLink = new AjaxLink("panelLink") { 

     @Override 
     public void onClick(final AjaxRequestTarget target) { 
      replaceContentPanel(getOverviewPanel(), target); 
     } 

     @Override 
     public boolean isVisible() { 
      return !(content instanceof OverviewPanel); 
     } 
    }; 
    breadCrumbContainer.add(panelLink); 
    panelLink.add(new Label("panelLabel", new Model<String>() { 
     @Override 
     public String getObject() { 
      //some dynamic content for example: 
      return contentPanel.getClass().getName(); 
     } 
    })); 
} 

public void replaceContentPanel(final Component replacer, final AjaxRequestTarget target) { 
    content.replaceWith(replacer); 
    content = replacer; 
    if (target != null) {   
     target.add(contentContainer); 
     target.add(breadCrumbContainer); 
    } 
} 

Home Page Label i są łatwe. Ta dla Panelu musi być aktualizowana za każdym razem, gdy aktualizuję zawartość Panel z. Byłem pewien, że linia target.add(breadCrumbContainer); zrobi to. Jednak jest pusty. Etykieta nic nie pokazuje.

Miałem nadzieję znaleźć odpowiedź - co jest chyba oczywiste - podczas pisania pytania, ale wciąż mi się wymyka, więc mam nadzieję, że ktoś zauważy mój błąd.

+2

Zastanawiam się, dlaczego nie skorzystać z komponentów bułki breadcrumb. Sprawdź przykład na stronie wicketstuff: http://wicketstuff.org/wicket/breadcrumb/ – magomi

+0

To jest dobry pomysł, zajrzę w to. Zastanawiam się jednak, dlaczego etykieta się nie wyświetla? – Yashima

Odpowiedz

10

Podczas odtwarzania z widocznością komponentu za pośrednictwem Ajax, konieczne jest użycie setOutputMarkupPlaceholderTag(true), oprócz setOutputMarkupId(true) . Zauważ, że setOutputMarkupPlaceholderTag(true) automatycznie oznacza setOutputMarkupId(true).

Powodem takiego działania jest to, że gdy komponent zostanie odświeżony przez Ajax (dodając go do AjaxRequestTarget), Wicket zwraca odświeżony znacznik w odpowiedzi Ajax, dzięki czemu zostanie zastąpiony przez JS-DOM API przez Ajax metoda wywołania zwrotnego. Tak więc dla funkcji JS, która zastąpi otrzymany znacznik do pracy, konieczne jest odniesienie do węzła DOM, który ma zostać zastąpiony (atrybut HTML id). Dlatego potrzebny jest setOutputMarkupId(true).

Podczas zmiany widoczności, jeśli komponent nie jest widoczny, Wicket nie generuje żadnych znaczników dla składnika, co jest wspaniałe, ale ma tę wadę. Jeśli niewidoczny komponent okaże się widoczny w następującym żądaniu ajax, jego znacznik zostanie skutecznie zwrócony w odpowiedzi Ajax. Ale ponieważ składnik nie był widoczny, nie będzie on istnieć w oryginalnym znaczniku, a zastąpienie węzła DOM w czasie wywołania nie będzie możliwe. W tym momencie wchodzi do akcji metoda setOutputMarkupPlaceholderTag(true), owijając niewidoczny komponent w znaczniku zastępczym (tj. <div>), który zawsze będzie renderowany przy użyciu odpowiedniego atrybutu HTML id.

+0

to brzmi naprawdę interesująco, będę sprawdzać, thx – Yashima

+0

Jeśli to naprawdę jest problem, powinieneś dostać błąd javascript podczas wykonywania metody wywołania zwrotnego, w 'document.getElementById (id) ze względu na' id''s nieistniejącego w DOM. –

+0

Xavi López jest poprawny, ale nie musisz ustawiać setOutputMarkupPlaceholderTag (true) oprócz setOutputMarkupId (true). Wystarczy tylko pierwszy, ponieważ ustawi drugi również na prawdziwy. –