MVC中的自动保存(ASP.NET)

10

我正在实现一个管理公司数据的Web系统。

我们使用了MVC(更具体地说是ASP.NET MVC 4),但我对它完全不熟悉。

我遇到的问题是,我们计划使用自动保存,就像Gmail一样。我们打算使用变更事件队列,并定期通过ajax提交更改。起初我想使用JavaScript,但不确定这是否是MVC的最佳方式。

另一个问题是,用户输入的某些信息不在表单中,而是在表格中。此外,页面布局有些稀疏,我不认为我可以将所有输入包装成单个表单,或者甚至应该这样做。

我的问题是:

  1. 使用MVC实现自动保存的最佳方法是什么,是否应该使用JavaScript?
  2. JavaScript中是否有任何库或特性可用于实现队列,或者我应手动实现?
  3. 同时,我能否使用表单包装表格行?

注意: 我看到有人建议使用localstorage或其他客户端持久性,但我需要服务器持久性,而且页面上甚至没有保存按钮。

提前感谢你的帮助;)

7个回答

13

您可以为不在表单中的元素添加form="myformid"属性,将其包含在表单中。我会在开头为所有元素添加data-dirty="false"属性,并附加更改事件,将更改元素的data-dirty属性更改为true。然后您可以每30秒保存一次表单(获取具有data-change=true的元素并传递给服务器)。保存后,每个元素的数据变脏状态再次变为false。以下是使用jQuery实现自动保存的示例:

window.setInterval(function(){
    var dirtyElements = $('#myformid').find('[data-dirty=true]').add('[form=myformid][data-dirty=true]');
    if(dirtyElements.length > 0){
        var data = dirtyElements.serialize();
        $.post('saveurl', data, function(){
            dirtyElements.attr('data-dirty', false);
            alert('data saved successfully');
        });
    }
}, 30000); // 30 seconds

将事件附加到表单的所有元素:

$(function(){
    var formElements = $('#myformid')
                           .find('input, select, textarea')
                           .add('[form=myformid]')
                           .not(':disabled')
                           .each(function(){
                                $(this).attr('data-dirty', false).change(function(){
                                    $(this).attr('data-dirty', true);
                                });
                           });
});

1
所有其他答案都非常好,但是你的数据脏建议让我印象深刻。真聪明 ;) 还有使用表单属性的好主意,我之前不知道这个。 - 7hi4g0
1
@7hi4g0 我很高兴我的答案有所帮助,但要注意表单属性,因为它是HTML5的特性,可能不受一些旧浏览器支持。 - karaxuna
这个回答很好,但是当有验证错误时会发生什么?那些错误会如何返回并在用户界面中显示? - Ben

3

答案...

  1. 一定要使用JavaScript和AJAX,这样用户在做出更改时页面就不会不断刷新。
  2. 我不知道有没有任何库可用,但我很乐意手工完成这项工作。使用JavaScript检测更改,然后通过AJAX发布数据。
  3. 您可以使用FormCollection参数或经典的Form["fieldname"]方法从控制器访问任何表单字段。只要您的表格单元格具有唯一的name值,就可以获取数据。

2
we can Auto save form using Ajax 
function AutoSaveMyForm(spanid) {
    var dataToPost = $("form").serialize()
    $.ajax({
        type: "POST",
        url: "/MyController/AutoSaveActionMethod",
        data: dataToPost,
        cache: false,
        success: function(resultdata) {
            if (resultdata['Code'] == '1') { // show success saved
                console.log(resultdata['ResultMsg']);
                if (spanid == "SaveLastStep") {
                    window.location = "/Dashboard/Index";
                }
                $('#' + spanid).html('Save Successfully.');
            } else if (resultdata['Code'] == '0') { // show error
                console.log(resultdata['ResultMsg']);
                $('#' + spanid).html('Not Saved');
            } else { // an error has occured
                $('#' + spanid).html('Error Generated.');
            }
        }
    });
}

window.setInterval(function() {
    AutoSaveMyForm('SpanIdToShowResult')
}, 60000); // 1 min

By using set interval method we can call javascript method which call ajax to save form and pass any span id to get result back

添加一些描述信息。这将比仅仅有一段代码更有帮助。 - Mathews Sunny

2

1) 使用JavaScript!jQuery可以很容易地使用AJAX调用在后台异步执行自动保存。

2) 据我所知,没有这样的功能,但不应该太难实现。

3) 不幸的是,你不能这样做,但你可以尝试类似于以下的方法:

<table id="mainTable">
 <tr>
  <td>
   <form id="someForm">
        <table class="aSubTable">
         <tr>
          <td><!-- fields go here --></td>
          <td><!-- fields go here --></td>
         </tr>
        </table>
   </form>
  </td>
 <tr>
</table>
(我知道这个示例代码没有利用 Razor,但是很容易弄清楚哪些部分需要替换为 Razor 以适应您自己的需求)

2
  1. 那真的是你唯一的选择。如果你没有使用Ajax提交表单,那么你将会经历整个页面的重新加载。这似乎不是你想要的。

  2. 有很多方法可以实现这个功能(也可以看看karaxuna刚刚发布的答案)。你可以附加一个事件到所有的输入框中,任何时候只要它们中的任何一个发生改变,就使用计时器保存数据。如果发生另一个更改事件,则重置计时器,以便不为每个更改事件保存数据。

    或者,如果你不需要它那么复杂,只需使用简单的计时器定期保存X分钟,而不管是否输入了任何新数据。

  3. 你可以在form中放置一个表格;这没有什么问题。我建议使用适当的输入框,这样很容易将数据序列化并发送到服务器。


1
你可以使用SignalR hub在页面和服务器之间动态通信。有关此技术的详细信息,请参见https://github.com/SignalR/SignalR/wikihttp://signalr.net/
这样,您就可以直接向服务器发送更改事件。您可以在JavaScript中使用生产者-消费者模型来限制它们的速度,但是SignalR的性能足够好,您应该能够做到不必这样做。
您可以在表单中嵌入表格,但是SignalR使用不同的客户端到服务器的通信方式。
祝您好运。

非常有趣的建议;)。我会向我的团队提出,也许我们会在另一个项目中使用它,但恐怕不会在这个项目中使用 :/。 - 7hi4g0
SignalR很棒,但不适合初学者开始mvc 4开发。 - Tom Stickel

0

仅针对您的问题1的部分答案:是的,mvc 4开箱即用,与javascript(jquery)和ajax非常兼容。

上面的答案向您展示了在razor视图中编写javascript / ajax的一些方法,然后您将与控制器通信(该控制器应从“模型”获取数据),然后整个.net mvc框架体验的一部分与各种设置相关联,您可以在web.config中进行测试,然后当您将值更改为false时。

例如

在您的web.config中,您将看到

<appSettings>
    <add key="webpages:Version" value="2.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="PreserveLoginUrl" value="true" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

MVC 3甚至在这方面表现得非常出色:

<appSettings>
    <add key="webpages:Version" value="1.0.0.0" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接