2013-06-07 14 views
5

W moim szablonie Velocity (plik .vm) w jaki sposób mogę przechodzić przez wszystkie zmienne lub atrybuty obecne w VelocityContext? W odniesieniu do poniższego kodu chciałbym, aby szablon zapisał nazwy i liczbę wszystkich owoców przekazanych w kontekście.Jak zapętlić wszystkie zmienne w VelocityContext?

Map<String, Object> attribues = ...; 
attribues.put("apple", "5"); 
attribues.put("banana", "2"); 
attribues.put("orange", "3"); 

VelocityContext velocityContext = new VelocityContext(attribues); 
velocityEngine.mergeTemplate(templateLocation, encoding, velocityContext, writer); 

Odpowiedz

4

Domyślnie nie można tego zrobić, ponieważ nie można zdobyć obiektu kontekstowego. Ale możesz umieścić kontekst w kontekście.

Java:

attributes.put("vcontext", attributes); 

.vm:

#foreach ($entry in $vcontext.entrySet()) 
    $entry.key => $entry.value 
#end 

Skoro czytasz kontekst żywo a także wykonywanie kodu, który modyfikuje mapę, masz zamiar dostać się wyjątki. Więc najpierw najlepiej zrobić kopię mapy:

#set ($vcontextCopy = {}) 
$!vcontextCopy.putAll($vcontext) 
#foreach ($entry in $vcontextCopy.entrySet()) 
    ## Prevent infinite recursion, don't print the whole context again 
    #if ($entry.key != 'vcontext' && $entry.key != 'vcontextCopy') 
    $entry.key => $entry.value 
    #end 
#end 
+0

Dziękuję. Szukałem potwierdzenia, że ​​nie jest to bezpośrednio możliwe. Jednak gdy wykonam twój kod, metoda 'Foreach.render' Velocity rzuca' ConcurrentModificationException'. Czy to działa dla ciebie? Używam Velocity 1.7. – Somu

+0

Czy robisz cokolwiek innego oprócz drukowania wyniku, jak w moim przykładzie? Jedna z możliwości polega na tym, że zmienna '$ entry' jest dodawana do kontekstu po otrzymaniu wpisów, co w rzeczywistości wywołuje' ConcurrentModificationException'. Jednym szybkim rozwiązaniem jest użycie 'ConcurrentHashMap' zamiast prostej' HashMap' dla zmiennej 'attributes'. –

+0

Nie, nie robię niczego poza prostą pętlą i drukowaniem. Używanie 'ConcurrentHashMap' ciekawie wyrzuca' StackOverflowError'! Nadal przyjmuję twoją odpowiedź na potwierdzenie, że nie ma bezpośredniego sposobu na uzyskanie dostępu do kontekstu z szablonu. – Somu

2

jak mogę pętli wszystkich zmiennych lub atrybuty obecne w VelocityContext?

Jeśli nie zrozumiałem cię źle, czy chcesz wiedzieć, jak przeglądać pary klucz/wartość znajdujące się na mapie, z której skonstruowano obiekt?

Jeśli tak, możesz wywołać metodę internalGetKeys(), która zwróci tablicę kluczy zawartą w obiekcie VelocityContext.

Następnie przeprowadź pętlę przez wszystkie klawisze i użyj wartości internalGet(), aby uzyskać wartość przypisaną do każdego klawisza.

To byłoby coś takiego:

 VelocityContext velocityContext = new VelocityContext(attribues); 
     Object[] keys = velocityContext.internalGetKeys(); 

     for(Object o : keys){ 
      String key = (String)o; 
      String value = (String)velocityContext.internalGet(key); 
      System.out.println(key+" "+value); 
     } 
+0

Dzięki ZouZou, myślę, że poprawnie zrozumiałeś mój problem. Czy mógłbyś mi pomóc, jak nazwać 'internalGetKeys()' i 'internalGet()' z pliku szablonu .vm? Szukam brakującego łącza w '#foreach ($ key w internalGetKeys()) $ key # end' – Somu

+0

@Somu Sprawdź moją edycję, mam nadzieję, że pomoże –

+0

Jeszcze raz dziękuję. Jednak szukałem sposobu na wywoływanie tych metod z szablonu Velocity (plik .vm). – Somu

Powiązane problemy