触发 Spring 没有页面的 MVC 控制器方法 redirect/refresh
Triggering Spring MVC controller method without page redirect/refresh
我想从 Thymeleaf 视图触发 Spring MVC 控制器方法而不从该方法返回任何内容并且不刷新页面。
我有以下 HTML 页面:
<!-- 'block item' button code-->
<div class="row">
<form method="get" th:action="@{'/items/block/' + ${item.itemId}}">
<button type="submit" class="btn btn-warning">block item</button>
</form>
</div>
相关控制器如下所示:
@GetMapping("/items/block/{itemId}")
@ResponseStatus(value = HttpStatus.OK)
public void blockItem(@PathVariable String itemId) {
itemService.blockItem(itemId);
}
itemService.blockItem(itemId)
调用只是更改数据库中相关 item
对象的相应布尔属性。
目前,每次当我按下 阻止项目 按钮触发此方法时,我都会被重定向到 URL,例如 http://localhost:8080/item/block/7C4A3744375523
。
我不想做任何重定向,只是执行相关的服务方法逻辑。我还需要从视图中删除相关项 div,但我可以使用 JavaScript.
非常简单地完成此操作
我该怎么做?谢谢。
您的按钮定义为 type
submit
.
因此,当您单击它时,将提交表单。
要防止这种默认行为,您需要做几件事:主要思想是为表单 submit
事件定义一个处理程序,并使用 Javascript 执行实际的服务器调用。
您可以在 different ways 中执行此操作,但我认为最好使用事件处理程序来定义所需的行为并将 HTML 代码与 Javascript 尽可能分开可能。
此外,您似乎正在遍历项目列表。
考虑到这两点,请考虑以下代码片段:
<script>
// We use the DOMContentLoaded event (https://developer.mozilla.org/en-US/docs/Web/API/Document/DOMContentLoaded_event)
// but please, register the form event as you consider appropriate
document.addEventListener('DOMContentLoaded', () => {
// Register form submit event handler for every form in your page
const forms = document.querySelectorAll('form');
if (forms) {
forms.forEach(f => {
let action = f.action;
f.addEventListener('submit', (event) => {
// prevent default behavior, i.e., form submission
event.preventDefault();
// perform server side request. you can use several options
// see https://developers.google.com/web/updates/2015/03/introduction-to-fetch, for instance
// For example, let's use fetch (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
fetch(action)
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
console.log('Request successfully completed');
})
.catch((error) => {
console.error('There has been a problem while contacting server:', error);
});
});
});
}
});
</script>
事实上,您可以去掉表格。请考虑一种稍微不同的方法。首先,在遍历您的项目时,生成以下 HTML 块(如果您愿意,可以使用 data
或任何自定义属性来存储当前处理的项目 ID):
<!-- 'block item' button code-->
<div class="row">
<button type="button" class="btn btn-warning item-button" th:id="${item.itemId}">block item</button>
</div>
现在,以与上述类似的方式,为每个项目按钮注册处理程序:
<script th:inline="javascript">
document.addEventListener('DOMContentLoaded', () => {
// Register handlers for every button
const buttons = document.querySelectorAll('.item-button');
if (buttons) {
buttons.forEach(b => {
b.addEventListener('click', (event) => {
let itemId = b.getAttribute('id');
let link = /*[[@{/items/block/}]]*/ 'link';
// Perform server side request
fetch(link + itemId)
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
console.log('Request successfully completed');
})
.catch((error) => {
console.error('There has been a problem while contacting server:', error);
});
});
}
}
});
</script>
导致重定向的不是 Thymeleaf 或 Spring MVC,而是 form
标签中的 submit
按钮。您需要覆盖此按钮的行为以通过 Ajax 发送表单数据并自行处理响应(基本上 - 忽略它) - 例如使用 jQuery 它可能看起来像:
<!-- 'block item' button code-->
<div class="row">
<form id="someFormId" method="get" th:action="@{'/items/block/' + ${item.itemId}}">
<button type="submit" class="btn btn-warning">block item</button>
</form>
</div>
//...
$('#someFormId').submit(function(e) {
e.preventDefault();
$.ajax({
type: 'GET',
url: '@{'/items/block/' + ${item.itemId}}',
data: $(this).serialize(),
// here you can define some actions for beforeSend, success, etc...
// for example to just ignore:
success: function(){}
});
})
有很多想法可以解决这个问题。请阅读例如
- Prevent redirect after form is submitted
- How to submit an HTML form without redirection
我想从 Thymeleaf 视图触发 Spring MVC 控制器方法而不从该方法返回任何内容并且不刷新页面。
我有以下 HTML 页面:
<!-- 'block item' button code-->
<div class="row">
<form method="get" th:action="@{'/items/block/' + ${item.itemId}}">
<button type="submit" class="btn btn-warning">block item</button>
</form>
</div>
相关控制器如下所示:
@GetMapping("/items/block/{itemId}")
@ResponseStatus(value = HttpStatus.OK)
public void blockItem(@PathVariable String itemId) {
itemService.blockItem(itemId);
}
itemService.blockItem(itemId)
调用只是更改数据库中相关 item
对象的相应布尔属性。
目前,每次当我按下 阻止项目 按钮触发此方法时,我都会被重定向到 URL,例如 http://localhost:8080/item/block/7C4A3744375523
。
我不想做任何重定向,只是执行相关的服务方法逻辑。我还需要从视图中删除相关项 div,但我可以使用 JavaScript.
非常简单地完成此操作
我该怎么做?谢谢。
您的按钮定义为 type
submit
.
因此,当您单击它时,将提交表单。
要防止这种默认行为,您需要做几件事:主要思想是为表单 submit
事件定义一个处理程序,并使用 Javascript 执行实际的服务器调用。
您可以在 different ways 中执行此操作,但我认为最好使用事件处理程序来定义所需的行为并将 HTML 代码与 Javascript 尽可能分开可能。
此外,您似乎正在遍历项目列表。
考虑到这两点,请考虑以下代码片段:
<script>
// We use the DOMContentLoaded event (https://developer.mozilla.org/en-US/docs/Web/API/Document/DOMContentLoaded_event)
// but please, register the form event as you consider appropriate
document.addEventListener('DOMContentLoaded', () => {
// Register form submit event handler for every form in your page
const forms = document.querySelectorAll('form');
if (forms) {
forms.forEach(f => {
let action = f.action;
f.addEventListener('submit', (event) => {
// prevent default behavior, i.e., form submission
event.preventDefault();
// perform server side request. you can use several options
// see https://developers.google.com/web/updates/2015/03/introduction-to-fetch, for instance
// For example, let's use fetch (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
fetch(action)
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
console.log('Request successfully completed');
})
.catch((error) => {
console.error('There has been a problem while contacting server:', error);
});
});
});
}
});
</script>
事实上,您可以去掉表格。请考虑一种稍微不同的方法。首先,在遍历您的项目时,生成以下 HTML 块(如果您愿意,可以使用 data
或任何自定义属性来存储当前处理的项目 ID):
<!-- 'block item' button code-->
<div class="row">
<button type="button" class="btn btn-warning item-button" th:id="${item.itemId}">block item</button>
</div>
现在,以与上述类似的方式,为每个项目按钮注册处理程序:
<script th:inline="javascript">
document.addEventListener('DOMContentLoaded', () => {
// Register handlers for every button
const buttons = document.querySelectorAll('.item-button');
if (buttons) {
buttons.forEach(b => {
b.addEventListener('click', (event) => {
let itemId = b.getAttribute('id');
let link = /*[[@{/items/block/}]]*/ 'link';
// Perform server side request
fetch(link + itemId)
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
console.log('Request successfully completed');
})
.catch((error) => {
console.error('There has been a problem while contacting server:', error);
});
});
}
}
});
</script>
导致重定向的不是 Thymeleaf 或 Spring MVC,而是 form
标签中的 submit
按钮。您需要覆盖此按钮的行为以通过 Ajax 发送表单数据并自行处理响应(基本上 - 忽略它) - 例如使用 jQuery 它可能看起来像:
<!-- 'block item' button code-->
<div class="row">
<form id="someFormId" method="get" th:action="@{'/items/block/' + ${item.itemId}}">
<button type="submit" class="btn btn-warning">block item</button>
</form>
</div>
//...
$('#someFormId').submit(function(e) {
e.preventDefault();
$.ajax({
type: 'GET',
url: '@{'/items/block/' + ${item.itemId}}',
data: $(this).serialize(),
// here you can define some actions for beforeSend, success, etc...
// for example to just ignore:
success: function(){}
});
})
有很多想法可以解决这个问题。请阅读例如
- Prevent redirect after form is submitted
- How to submit an HTML form without redirection