扩展在Autosave in MVC (ASP.NET)找到的示例,我想在我的应用程序中创建一个部分重用。我有一个带有选项卡式布局的视图,每个选项卡都有自己的表单,这会导致问题,即每个表单都会尝试每次都提交,并且只有文档中的第一个时间戳更新。我理解为什么会这样,但我不知道如何解决它。
Partial的cshtml:
<div class="form-group">
<label class="control-label col-lg-2" for=""> </label>
<div class="col-lg-10">
<span class="help-block" id="autosaveTime">Not Autosaved</span>
</div>
</div>
@{
var autosaveString = "'" + @ViewData["autosaveController"] + "'";
if (ViewData["autosaveAction"] != null && ViewData["autosaveAction"] != "")
autosaveString += ", '" + ViewData["autosaveAction"] + "'";
}
<script type="text/javascript">
$(document).ready(function () {
autosave(@Html.Raw(autosaveString));
});
</script>
使用Javascript:
//methodName is optional-- will default to 'autosave'
function autosave(controllerName, methodName)
{
methodName = typeof methodName !== 'undefined' ? methodName : 'autosave'
var dirty = false;
$('input, textarea, select').keypress(function () {
dirty = true;
});
$('input, textarea, select').change(function () {
dirty = true;
});
window.setInterval(function () {
if (dirty == true) {
var form = $('form');
var data = form.serialize();
$.post('/' + controllerName + '/' + methodName, data, function () {
$('#autosaveTime').text("Autosaved at " + new Date);
})
.fail(function () {
$('#autosaveTime').text("There was a problem autosaving, check your internet connection and login status.");
});
dirty = false;
}
}, 30000); // 30 seconds
}
我有2个关于如何修复它的想法,但不确定哪个更易于维护/可行:
closest
函数来查找放置自动保存块的表单,并使用它来执行我使用#1明确执行的操作。答案 0 :(得分:1)
首先,使用Razor帮助程序的Html扩展名创建URL(在JavaScript中动态拼接这样的URL是不必要的风险)。把它拿到选项卡控件的数据属性中,如下所示:
<div class="tab autosave" data-action-url='@Html.Action("Action", "Controller")'>
<form>
<!-- Insert content here -->
</form>
</div>
然后,你会想要这样的东西 - 不要在任何地方都包含它,并完全从你的部分中删除javascript:
$(function() {
// Execute this only once, or you'll end up with multiple handlers... not good
$('.autosave').each(function() {
var $this = $(this),
$form = $this.find('form'),
dirty = false;
// Attach event handler to the tab, NOT the elements--more efficient, and it's always properly scoped
$this.on('change', 'input select textarea', function() {
dirty = true;
});
setInterval(function() {
if(dirty) {
// If your form is unobtrusive, you might be able to do something like: $form.trigger('submit'); instead of this ajax
$.ajax({
url : $this.data('action-url'),
data : $form.serialize()
}).success(function() {
alert("I'm awesome");
dirty = false;
});
}
}, 30 * 1000);
});
});