Spring MVC 3.2 Tymeleaf Ajax

Buduję aplikację za pomocą Spring MVC 3.2 i Thymeleaf templating engine. Jestem początkujący w Tymeleaf.

Mam wszystko działa, w tym Thymeleaf ale zastanawiałem się czy ktoś zna prosty i przejrzysty toturial jak zrobić proste żądanie Ajax do kontrolera i w efekcie renderować tylko część szablonu (fragment).

Moja aplikacja ma wszystko skonfigurowane (Spring 3.2, spring-security, thymeleaf, ...) i działa zgodnie z oczekiwaniami. Teraz chciałbym zrobić Ajax request (dość proste z jQuery, ale nie chcę nie używać, ponieważ Thymeleaf w swoim tutorialu, Rozdział 11: Rendering Template Fragments (link ) wspomina, że można to zrobić z fragmentami.

Obecnie mam w swoim kontrolerze

@RequestMapping("/dimensionMenuList")
public String showDimensionMenuList(Model model) {

    Collection<ArticleDimensionVO> articleDimensions;
    try {
        articleDimensions = articleService.getArticleDimension(ArticleTypeVO.ARTICLE_TYPE);
    } catch (DataAccessException e) {
        // TODO: return ERROR
        throw new RuntimeException();
    }

    model.addAttribute("dimensions", articleDimensions);

    return "/admin/index :: dimensionMenuList";
}

Część widoku, w której chciałbym zamienić <ul></ul> pozycje menu:

<ul th:fragment="dimensionMenuList" class="dropdown-menu">
    <li th:unless="${#lists.isEmpty(dimensions)}" th:each="dimension : ${dimensions}">
        <a href="#" th:text="${dimension.dimension}"></a>
    </li>
</ul>
Każda wskazówka jest bardzo doceniana. Zwłaszcza, jeśli nie muszę zawierać więcej frameworków. To już za dużo dla java web app, Jak to jest.
Author: Mahozad, 2014-01-08

2 answers

Oto podejście, na które natknąłem się w blogu :

Nie chciałem używać tych frameworków, więc w tej sekcji używam jQuery do wysyłania żądania AJAX na serwer, oczekiwania na odpowiedź i częściowej aktualizacji widoku (renderowanie fragmentów).

Formularz

<form>
    <span class="subtitle">Guest list form</span>
    <div class="listBlock">
        <div class="search-block">
            <input type="text" id="searchSurname" name="searchSurname"/>
            <br />
            <label for="searchSurname" th:text="#{search.label}">Search label:</label>
            <button id="searchButton" name="searchButton" onclick="retrieveGuests()" type="button" 
                    th:text="#{search.button}">Search button</button>
        </div>

        <!-- Results block -->
        <div id="resultsBlock">

        </div>
    </div>
</form>

Ten formularz zawiera tekst wejściowy z wyszukiwanym ciągiem (searchSurname), który zostanie wysłany na serwer. Istnieje również region (resultsBlock div), który zostanie zaktualizowany o odpowiedź otrzymane z serwera.

Gdy użytkownik kliknie przycisk, zostanie wywołana funkcja retrieveGuests ().

function retrieveGuests() {
    var url = '/th-spring-integration/spring/guests';

    if ($('#searchSurname').val() != '') {
        url = url + '/' + $('#searchSurname').val();
    }

    $("#resultsBlock").load(url);
}

Funkcja jQuery load wysyła żądanie do serwera pod podanym adresem url i umieszcza zwrócony HTML w podanym elemencie (resultsBlock div).

Jeśli użytkownik wprowadzi szukany ciąg, będzie szukał wszystkich gości o podanym nazwisku. W przeciwnym razie zwróci pełną listę gości. Te dwa żądania dotrą do następującego kontrolera request mappings:

@RequestMapping(value = "/guests/{surname}", method = RequestMethod.GET)
public String showGuestList(Model model, @PathVariable("surname") String surname) {
    model.addAttribute("guests", hotelService.getGuestsList(surname));

    return "results :: resultsList";
}

@RequestMapping(value = "/guests", method = RequestMethod.GET)
public String showGuestList(Model model) {
    model.addAttribute("guests", hotelService.getGuestsList());

    return "results :: resultsList";
}

Ponieważ Spring jest zintegrowany z Thymeleaf, będzie teraz mógł zwracać fragmenty HTML. W powyższym przykładzie łańcuch zwrotny "results:: resultsList" odnosi się do fragmentu o nazwie resultsList, który znajduje się na stronie results. Spójrzmy na tę stronę wyników:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:th="http://www.thymeleaf.org" lang="en">

<head>
</head>

<body>
    <div th:fragment="resultsList" th:unless="${#lists.isEmpty(guests)}" id="results-block">
        <table>
            <thead>
                <tr>
                    <th th:text="#{results.guest.id}">Id</th>
                    <th th:text="#{results.guest.surname}">Surname</th>
                    <th th:text="#{results.guest.name}">Name</th>
                    <th th:text="#{results.guest.country}">Country</th>
                </tr>
            </thead>
            <tbody>
                <tr th:each="guest : ${guests}">
                    <td th:text="${guest.id}">id</td>
                    <td th:text="${guest.surname}">surname</td>
                    <td th:text="${guest.name}">name</td>
                    <td th:text="${guest.country}">country</td>
                </tr>
            </tbody>
        </table>
    </div>
</body>
</html>

Fragment, który jest tabelą z zarejestrowanymi gośćmi, zostanie wstawiony do bloku wyników.

 66
Author: Sohail,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-06 03:07:04

Tylko renderowanie Thymeleaf fragments działa również dobrze z ModelAndView.

Twój kontroler

@RequestMapping(value = "/feeds", method = RequestMethod.GET)
public ModelAndView getFeeds() {
    LOGGER.debug("Feeds method called..");
    return new ModelAndView("feeds :: resultsList");
}

Twój Widok

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">

<head></head>
<body>
    <div th:fragment="resultsList" id="results-block">
        <div>A test fragment</div>
        <div>A test fragment</div>
    </div>
</body>
</html>

Co jest faktycznie renderowane

<div id="results-block">
    <div>A test fragment</div>
    <div>A test fragment
    </div>
</div>
 3
Author: Abdullah Khan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-25 09:06:08