【问题标题】:asp.net webforms and jquery: How to save/restore jquery state between postbacks?asp.net webforms 和 jquery:如何在回发之间保存/恢复 jquery 状态?
【发布时间】:2010-10-04 18:48:41
【问题描述】:

我正在构建一个 asp.net webforms (3.5 sp1) 应用程序,使用 jquery 来为 UI 设置动画,更改其状态。在我开始进行回发之前,它一直运行良好,此时 UI 显然会将自身重置为其初始状态。

所以我的问题是,在回发之间保存和恢复 jquery/UI 状态的最佳做法是什么?

谢谢,埃吉尔。

更新:非常感谢大家,提供了很好的意见,可惜我不能将多个答案标记为“答案”。

【问题讨论】:

    标签: asp.net jquery user-interface webforms postback


    【解决方案1】:

    你有两个选择:

    • 客户端 cookie
    • 通过回发或 Web 方法调用在服务器端存储 UI 设置

    第二个选项将需要更多的努力,但允许您提供“便携式”UI 设置,无论客户端机器如何,都可以应用于用户。如果设置是“丢弃”,我会选择客户端 cookie。

    如何使用 javascript 和 cookie:

    http://techpatterns.com/downloads/javascript_cookies.php

    我通常通过回发将 UI 设置服务器端存储在数据库中,但是如果用户通过 jQuery 更改他们的 UI 并且您希望保留这些更改,我可能会这样做:

    • 将脚本管理器添加到您的 aspx 页面
    • 设置 EnablePageMethods="true"
    • 在您的代码隐藏中创建一个 WebMethod
    • 在更新 UI 的 jQuery 方法中,添加对 WebMethod 的调用并传回 UI 设置
    • 将传递给 WebMethod 的所有设置存储在数据库中
    • 然后当用户下次访问该页面时,要么获取设置并填充尽可能多的控件服务器端,要么使用 jQuery 就绪方法调用另一个从数据库中获取 UI 设置的 Web 方法, 将它们传递回 jQuery,以便您填充控件。

    这是一篇关于 jQuery 和 WebMethod 调用的不错的文章:

    http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/

    您需要注意的问题是 EventValidation;如果您在页面生命周期范围之外获取控制值,然后期望在回发时使用这些设置,您将遇到麻烦。例如,通过 web 方法向下拉列表添加值会在回发时引发错误,除非在构建页面时这些值也被添加到下拉列表中。

    【讨论】:

    • 如何在服务器端存储 UI 设置?使用隐藏字段还是?
    【解决方案2】:

    我通常通过 AJAX 在会话中存储诸如菜单状态或过滤器(div 中的一组输入)可见性等内容。当菜单展开或过滤器显示时,单击处理程序将向 Web 服务触发 AJAX 事件,该 Web 服务将记录菜单状态或过滤器在用户会话中的可见性。在回发时,我使用与每个菜单/过滤器对应的会话变量通过 CSS 设置它的初始状态。我发现这是更好的用户体验,因为如果您在客户端进行更改,则在加载后由 javascript 更新页面时页面不会闪烁

    示例——因为我在路上,这不是来自项目的实际代码,可能不完整。使用 jQuery。 Web 服务的 URL 将取决于您如何实现 Web 服务。我正在使用 ASP.NET MVC(大部分)所以我的将是一个控制器操作。

    <script type='text/javascript'>
        $(document).ready( function() {
           $('#searchFilter').click( function()  {
               var filter = $(this);
               var filterName = filter.attr('id');
               var nowVisible = filter.css('display') === 'none';
               if (nowVisible) {
                  filter.show();
               }
               else {
                  filter.hide();
               }
               $.post('/controller/SetFilterVisibility',
                      { name: filterName, visibility: nowVisible } );
           });
        });
    </script>
    
    
    <div id='searchFilter' <%= ViewData["searchFilterVisibility"] %> >
        ...
    </div>
    

    服务器端代码

    [AcceptVerbs( HttpVerbs.POST )]
    [Authorization]
    public ActionResult SetFilterVisibility( string name, bool visible )
    {
        Session[name] = visible;
        return Content( string.Empty );  // not used... 
    }
    
    [AcceptVerbs( HttpVerbs.GET )]
    [Authorization]
    public ActionResult SomeAction( int id )
    {
        ...
        ViewData["searchFilterVisibility"] = Session["searchFilter"];
        ...
        return View();
    }
    

    【讨论】:

    • 听起来是个好主意。您介意发布一些示例代码吗?
    【解决方案3】:

    我认为您指的是在回发之间保存 ui 小部件的状态(而不是保存用户首选项)。

    在特定的一系列交互之后(例如,展开此树节点、单击该网格行等)后,该状态中的大部分仅适用于特定小部件、特定用户。这些东西不必进入数据库,甚至不必进入会话,除非跨页面加载恢复状态对您很重要。

    我倾向于将所有东西放入一两个对象中,例如:

    treeState.expandedNodeId = 'foo';
    gridState.selectedRowIndex = 3;
    

    然后我定期将其保存在隐藏字段中:

    $('.treeState').val(Sys.Serialization.JavaScriptSerializer.serialize(treeState));
    

    等等

    该值与回发结果一起发回,我只需deserialize 它并从保存的值中恢复我的小部件。烦人,但效果很好。

    【讨论】:

    • 这是working JSFiddle。如果状态保存在表单提交时,如果用户未通过服务器端验证,它们可以恢复。
    【解决方案4】:

    我使用的是 HTML5 存储,您可以选择如何持久化(本地存储或每个浏览器会话)。如果您担心非 HTML5,您可以使用 Amplify.Storage。缺点是您必须编写代码来调用保存/读取。我正在寻找一种自动化的方法,如果有人有任何想法,请说。谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-31
      • 1970-01-01
      • 2016-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多