[英]Waiting for an async call to finish before submitting a form
这个有点棘手。
所以这是我的jQuery代码:
/**
* Updating websites
*/
$('.website').on('blur', function () {
var websiteId = this.id;
console.log(websiteId);
var website = this.value;
console.log(website);
fetch(`/api/edit/${websiteId}&${website}`).then(() => {
});
})
这是我的HTML
<form method="post">
<% for(let i = 0; i < websites.length; i++){ let website = websites[i]; %>
<fieldset id="site<%= i %>">
<p style="color: <% if(errorMsgs[i] === 'Wrong website address'){ %> red;<% } else { %> green;<% } %>
padding-bottom: 0;
padding-top: 10px;
margin-bottom: 0;"
class="">
<%= errorMsgs[i] %>
</p>
<div class="">
<input class="website"
name="website<%= i %>"
id="<%= i %>"
value="<%= website %>"
type="text"/>
<a href="/websites/edit/<%= i %>"
class="btn btn-info hide">
Edit
</a>
<a href="/websites/delete/<%= i %>"
data-id="<%= i %>"
class="btn btn-danger confirmation removeBtn">
Remove
</a>
</div>
</fieldset>
<% } %>
<button type="submit"
class="btn btn-primary col-sm-offset-2"
value="Generate a report"
name="generateReport"
data-toggle="modal"
data-target="#exampleModal">
Generate a report
</button>
<!-- Save button created using Javascript. In case JS is disabled -->
</form>
这是我的API
// GET: api/edit/_id - save updates
router.get('/edit/:_id&:url', (req, res, next) => {
Account.findById(req.user._id, (err, acc) => {
if (err) {
console.log(err);
} else {
acc.websites.set(req.params._id, req.params.url);
acc.save((err, webs) => {
if (err) {
console.log(err);
} else {
console.log('all good');
// res.redirect('/reports');
res.json(webs);
}
});
}
});
});
工作原理:用户将值输入到输入字段中,模糊时,我对API进行AJAX调用,该值保存在db中。 所有这些都有效。
不过有一个问题。 如果用户单击提交按钮,则提取没有时间运行。 这是有道理的。
但是我需要提交来等待值更新。 我当时正在考虑做些类似的事情,比如在submit按钮上添加一个preventDefault
,然后在保存之后,删除preventDefault
。
但是我不知道该怎么做,如果这是个好主意,甚至是没有道理的。
回顾一下:我需要提交表单以等待AJAX调用完成。
此<% smth %>
只是EJS
模板系统。 不应影响所有工作方式。
看起来fetch()
返回了一个promise。 将这些承诺保存在共享变量中。 在您的提交按钮代码中,使用Promise.all()
等待所有的诺言得到解决。 就像是:
const fetchPromises = [];
$('.website').on('blur', function () {
var websiteId = this.id;
console.log(websiteId);
var website = this.value;
console.log(website);
var fetchPromise = fetch(`/api/edit/${websiteId}&${website}`).then(() => {
});
fetchPromises.push(fetchPromise);
});
$('form').on('submit', function (e) {
e.preventDefault();
Promise.all(fetchPromises).then(() => this.submit());
});
您可能要添加一些错误处理。 如果您的任何fetch()
调用均失败,则将阻止提交表单。 理想的情况是,失败的AJAX调用会导致向用户发送一些消息,该消息一旦被关闭,便会从fetchPromises
数组中删除promise,并且在被关闭之前,应禁用(实际上是可见的)提交按钮。
如何使用preventDefault
创建一个伪造的提交按钮,并使用display:none
隐藏真正的提交按钮呢? 然后,一旦获得AJAX成功,就可以在隐藏按钮上调用click()
函数。
您可以将按钮设置为禁用状态,向其添加侦听器,然后在.then()函数期间引发事件。
$('.website').on('blur', function () {
var elem = document.getElementById('submitButtonId');
// create the event
var isFinishedEvent = new Event('fetched');
elem.addEventListener('fetched', function() {
// logic to enable your button
}
var websiteId = this.id;
console.log(websiteId);
var website = this.value;
console.log(website);
fetch(`/api/edit/${websiteId}&${website}`).then(() => {
// Fire the event
elem.dispatchEvent(isFinishedEvent);
});
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.