mvc - 在多页面网格中存储复选框状态

时间:2010-09-30 14:25:38

标签: asp.net-mvc ajax

虽然这里有类似的问题,但没有一个给出完整的答案,所以我发布了一个新答案。

我有一个分页网格 - jqgrid - 每次都通过ajax,N行(10,20等等,具体取决于用户选择)从服务器接收数据。网格行模型中有一个布尔值,它将转换为显示行中的复选框。

当用户选中复选框然后导航到下一个网格页面时,复选框的状态显然会丢失。保存它的最佳方法是什么?我看到的两种可能性都不能完全满足我:

我可以在复选框点击时将所选实例的ID保存到全局javascript对象中。因此,当获得新数据集时,我可以迭代所有接收到的实例,寻找已经选择的实例。但是,如果有很多选定的实例,这可能意味着很多javascript操作和最终用户可能的减速。

我可以将选择存储在服务器上(会话,数据库,等等)。这样每次生成模型时,我都会用足够的值填充它的布尔参数。但是,这可能意味着当用户离开我的页面而不提交更改然后返回时,将恢复记录状态。我不确定这是否好。通常,我强烈反对在用户提交表单之前在服务器端存储任何内容。

那么,你会选择/提供什么?

我正在使用ASP.NET MVC 2.0,C#4.0,如果这很重要。

2 个答案:

答案 0 :(得分:1)

我已经通过在选择下一页时在隐藏的div中写入“已选中”复选框列表来解决这种情况。这样,客户端维护选择列表,并且不需要服务器交互。此外,当用户最终提交页面时,我只是遍历可见页面中的所有复选框和隐藏的div。

在我的系统中,即使在用户选择数百个项目的示例中,性能也不是问题。

答案 1 :(得分:1)

你的问题主要是关于在不涉及邪恶的webforms视图状态的ajax场景中保存状态。

但是,当viewstate用于保存您正在处理的场景中的状态时(与提供假装网页是一种winform的方法相反),没有任何问题。

那么,为什么不去追求两全其美并将价值存储在一个加密的隐藏领域,一种精益,卑鄙,聪明的人的观点呢?

当您请求下一页数据时,将现有的“viewstate”(如果有)加上新检查的项目传回服务器,解密服务器上的viewstate,查看其中的内容以及它是否与在下一页中,添加新的已检查项目列表,对其进行加密并将新的“viewstate”发送回用户。

我没有这样做,所以这只是一个想法。但是,它在逻辑上是可行的,而且非常实用。我说我没有使用网格做到这一点,但我已经做了很大的成功,设计了一个梦想的向导框架。

我的向导在用户填写表单时保留其状态,并且只有在最后一步中才会保留任何内容(如果有的话,取决于应用程序的要求)。

这个框架基于Steve Sanderson的书中描述的向导,但扩展到无论是否使用ajax都能无缝工作。并且有一个非常简单的API,用于从我的向导控制器派生的控制器。

使用此Onstate工作的代码从OnActionExecuting方法调用:

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
   var serialized = Request.Form["wizardData"];            
   if (serialized != null) // Form was posted containing serialized data
   {
      WizardData = (TModel)new MvcSerializer().Deserialize(serialized);
   }
}

然后在ViewResult中返回给用户:

<%= Html.Serialize("wizardData", Model)%>

在您的情况下,由于您只是分页数据,您需要序列化并加密wizardData对象的等效项,然后将其与JSON数据一起发送回存储在隐藏字段中的某个位置。

这有点模糊,因为向导不是分页数据的网​​格。但是这些原则(基本上是滚动你自己的视图状态)确实适用于这两种情况。