봄 MVC 3.2 티멜리프 아약스 프래그먼트
봄 MVC 3.2와 Tymeleaf 템플링 엔진으로 애플리케이션을 구축하고 있습니다.저는 타임리프 초보자입니다.
Tymeleaf를 포함한 모든 것이 동작하고 있습니다만, 컨트롤러에 대한 간단한 Ajax 요청과 결과적으로 템플릿의 일부만 렌더링하는 방법에 대해 알기 쉬운 토털리얼을 알고 계신 분이 있는지 궁금합니다.
내 앱은 모든 것을 설정했고(Spring 3.2, Spring-security, Tymeleaf 등) 예상대로 작동합니다.이제 Ajax 요청을 하고 싶습니다(jQuery는 매우 단순하지만 사용하고 싶지 않습니다). Tymeleaf는 튜토리얼 11장: Rendering Template Fragments (link)에서 fragment로 실행할 수 있다고 언급하고 있기 때문입니다.
현재 컨트롤러에 있는
@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";
}
뷰에서 대체하고 싶은 부분<ul></ul>뉴뉴: :
<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>
어떤 단서라도 대단히 감사합니다.특히 더 이상 틀을 짜지 않아도 된다면요.자바 웹 앱은 이미 너무 과하다.
블로그 투고에서 접한 접근방식은 다음과 같습니다.
이러한 프레임워크를 사용하고 싶지 않기 때문에 이 섹션에서는 jQuery를 사용하여 서버에 AJAX 요청을 전송하고 응답을 기다린 후 보기를 부분적으로 업데이트합니다(프래그먼트 렌더링).
폼
<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>
이 양식에는 서버로 전송되는 검색 문자열(searchSurname)이 포함된 입력 텍스트가 포함됩니다.서버로부터 수신한 응답으로 갱신되는 영역(resultsBlock div)도 있습니다.
사용자가 버튼을 클릭하면 retrieveGuests() 함수가 호출됩니다.
function retrieveGuests() {
var url = '/th-spring-integration/spring/guests';
if ($('#searchSurname').val() != '') {
url = url + '/' + $('#searchSurname').val();
}
$("#resultsBlock").load(url);
}
jQuery load 함수는 지정된 URL의 서버에 요청을 하고 반환된HTML을 지정된 요소에 배치합니다(resultsBlock div).
사용자가 검색 문자열을 입력하면 지정된 성을 가진 모든 게스트가 검색됩니다.그렇지 않으면 전체 게스트 목록이 반환됩니다.이들 2개의 요구는 다음 컨트롤러 요구 매핑에 도달합니다.
@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";
}
스프링은 Tymeleaf와 통합되어 있기 때문에 HTML의 fragment를 반환할 수 있습니다.위의 예에서 results :: resultsList는 results 페이지에 있는 resultsList라는 이름의 fragment를 참조하고 있습니다.다음 결과 페이지를 보겠습니다.
<!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는 게스트가 등록된 테이블로 결과 블록에 삽입됩니다.
렌더링만Thymeleaf fragments와도 잘 어울린다ModelAndView.
컨트롤러
@RequestMapping(value = "/feeds", method = RequestMethod.GET)
public ModelAndView getFeeds() {
LOGGER.debug("Feeds method called..");
return new ModelAndView("feeds :: resultsList");
}
고객님의 견해
<!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>
실제로 렌더링되는 것
<div id="results-block">
<div>A test fragment</div>
<div>A test fragment
</div>
</div>
Sohail의 훌륭한 답변의 대체 버전으로서, javascript를 사용하면 th: 오브젝트 전체를 컨트롤러로 전송하여 Tymeleaf를 폼에 통합할 수 있는 버전을 제공하고 싶습니다.많은 필드를 형성할 때 지저분해지거나 전혀 사용할 수 없는 @PathVariable을 사용할 필요가 없습니다.
폼(ID와 이름이 Strings인 객체를 반환하고 이러한 객체 중 일부를 값으로 포함하는 Map을 콤보박스에 공급하는 예제를 사용)에는 다음이 있습니다.
<form method="post" th:action="@{/yourMapping}" th:object="${object}" id="yourFormId">
<select th:field="*{mapOfObjects}">
<option
th:each="entry: ${mapOfObjects}"
th:value="${entry.value.id}"
th:text="${entry.value.name}" >
</option>
</select>
<p>Name:
<input type="text" th:field="*{name}" />
</p>
</form>
이 양식이 제출되면(예를 들어 제출 유형이 있는 버튼을 사용하여) 문서 전체가 교체됩니다.그러나 이 제출을 javascript로 대행 수신하여 ajax 방식으로 할 수 있습니다.이를 위해 함수를 사용하여 폼에 인터셉터를 추가합니다.먼저 다음 폼 바로 뒤에 대행 수신기를 추가하는 함수를 호출합니다.
<script>formInterceptor("yourFormId");</script>
기능은 다음과 같습니다(문서 머리글이나 필요에 따라 배치).
<script>
function formInterceptor(formName) {
var $form = $("#" + formName);
$form.on('submit', function(e) {
e.preventDefault();
$.ajax({
url : $form.attr('action'),
type : 'post',
data : $form.serialize(),
success : function(response) {
if ($(response).find('.has-error').length) {
$form.replaceWith(response);
}
else{
$("#ajaxLoadedContent").replaceWith(response);
}
}
});
});
};
</script>
양식이 제출될 때마다 이 함수가 트리거되어 다음과 같이 처리됩니다.
- 원본 양식 제출 금지
- 폼의 th:action에 정의된 URL을 사용하여 Ajax 콜을 발신합니다.
- 폼 데이터를 시리얼화합니다.컨트롤러는 이를 객체 내에서 수신할 수 있습니다.
- html 코드의 일부를 반환된 fragment로 바꿉니다.
교체된 부품은 다음과 같습니다.
<div id="ajaxLoadedContent"></div>
또한 컨트롤러는 다음과 같은 형식으로 th: 객체를 수신할 수 있습니다(개체를 개체 유형으로 바꾸고 "개체를 올바른 이름으로 바꾸기").
@PostMapping(value = /yourMapping)
public String ajaxCtrlExample(@ModelAttribute("object") Object object, Model model) {
return yourFragmentPath;
}
그게 다에요.ajax-version에서 필요한 모든 형식 뒤에 인터셉터를 추가하는 함수를 호출합니다.
언급URL : https://stackoverflow.com/questions/20982683/spring-mvc-3-2-thymeleaf-ajax-fragments
'programing' 카테고리의 다른 글
| angularjs 지시문에 대해 트랜슬루드 콘텐츠가 제공되었는지 감지합니다. (0) | 2023.03.16 |
|---|---|
| 헤더("Content-type: text/xml") 대신; (0) | 2023.03.16 |
| 각도 컨트롤러가 등록되지 않음 오류 (0) | 2023.03.16 |
| 다음 포스트 요청을 어떻게 처리할 것인가? (0) | 2023.03.16 |
| 경고:알 수 없는 DOM 속성 클래스입니다.className을 말하는 건가요? (0) | 2023.03.16 |