如何禁用或ASP.NET异步回发之前删除不必要的表单元素? [英] How do I disable or remove unnecessary form elements before an ASP.NET asynchronous postback?

查看:92
本文介绍了如何禁用或ASP.NET异步回发之前删除不必要的表单元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建立一个购物车页面,可以潜在地包含几十个独立的项目。每个项目都有一个包含可用于定制了好表单元素一个可折叠的面板。大部分的车被包裹在一个UpdatePanel让我能避免完全回发,当用户进行更改。当有购物车中的很多项目,当然有很多很多回发的元素,所有这些都包含在原始形式后,虽然每个岗位真的是只有一个元素(ChildrenAsTriggers = TRUE)的变化引起的。

I'm building a shopping cart page that could potentially contain dozens of separate items. Each item has a collapsible panel that contains several form elements that can be used to customize it. Most of the cart is wrapped in an UpdatePanel so that I can avoid a full postback when the user makes changes. When there are many items in the cart, there are of course many many postback elements, all of which are included in the raw form post, even though each post is really only triggered by the change of a single element (ChildrenAsTriggers=True).

我发现冗余形式的名称/值对的uncom pressed大小是25K。大小大概是在实践远小于由于浏览器(我假设浏览器经常COM preSS回发值,但没有去的麻烦来验证这个gzip的COM pression - 任何人都知道肯定?)我知道我在这里一个小肛门(你的个人资料之前,优化!),但我真的想找到一种方法来消除这种冗余数据。我想出了以下JavaScript:

I find that the uncompressed size of the redundant form name/value pairs is 25K. The size is probably far smaller in practice due to gzip compression in the browser (I assume browsers routinely compress the postback values, but haven't gone to the trouble to verify this -- anyone know for sure?) I know I'm being a little anal here ("profile before you optimize!") but I would really like to find a way to eliminate this redundant data. I came up with the following JavaScript:

Sys.WebForms.PageRequestManager.getInstance().add_beginRequest
(
  function(sender, args) {

    var elPostBackTrigger = args.get_postBackElement();

      // skip the first input element, which is expected to be the ScriptManager's hidden field
      removeNonEssentialPostBackValues(document.aspnetForm.getElementsByTagName("input"), elPostBackTrigger, 1);
      removeNonEssentialPostBackValues(document.aspnetForm.getElementsByTagName("select"), elPostBackTrigger);
      removeNonEssentialPostBackValues(document.aspnetForm.getElementsByTagName("textarea"), elPostBackTrigger);
   }
);

function removeNonEssentialPostBackValues(aElements, elPostBackTrigger, iFirstElement) {

    if (iFirstElement == undefined)
        iFirstElement = 0;

    for (var i = iFirstElement; i < aElements.length; ++i) {
        if
        (
            aElements[i] != elPostBackTrigger
            && aElements[i].name
            && aElements[i].name != ''
            && aElements[i].name.indexOf('_') != 0
        ) {
            aElements[i].removeAttribute('name');
            aElements[i].disabled = true;
        }
    }
}

我们的想法是,如果你删除一个表单元素的name属性,应该不再是成功的按HTML规范和ASP.NET应该从回发忽略它。当然,你不想与__VIEWSTATE,__EVENTTARGET,还是真的任何以下划线开头的混乱。而你不想要删除的回发触发器本身。

The idea is that if you remove the "name" attribute of a form element, it should no longer be "successful" as per the HTML spec, and ASP.NET should omit it from the postback. Of course you don't want to mess with __VIEWSTATE, __EVENTTARGET, or really anything that begins with an underscore. And you don't want to remove the postback trigger itself.

不幸的是,这对通过捕捉萤火虫回发值没有任何影响。看来,由PageRequestManager触发BeginRequest事件的时候,它已经产生的回发名称/值对。我觉得这是奇怪的,因为我会想象,对于BeginRequest事件的主要原因是让小的变化,以回发前的表单元素。也许PageRequestManager实际上并不产生名称/值对,而只是pre-产生哪些元素的列表将被纳入?调试到MS JavaScript库是很难苦读,我想知道是否有人在这里可以赐教。

Unfortunately, this has no effect on the postback values captured through Firebug. It seems that by the time the PageRequestManager fires the beginRequest event, it has already generated the postback name/value pairs. I find this strange, since I would imagine that the main reason for the beginRequest event is to make small changes to the form elements before postback. Maybe PageRequestManager doesn't actually generate the name/value pairs, but rather just pre-generates a list of which elements will be included? Debugging into the MS JavaScript libraries is hard slogging, and I was wondering if anyone could enlighten me here.

编辑1:我也尝试禁用除了表单元素,以消除他们的名字属性,但它并没有帮助。我通过Firebug的验证删除的BeginRequest事件完成之前,但不知何故ASP.NET仍增加了他们全部回发的元素是残疾人和名字。

EDIT 1: I also tried disabling the form elements in addition to removing their name attributes, but it didn't help. I verified through Firebug that the elements are disabled and names removed before the beginRequest event completes, but somehow ASP.NET still adds them all to the postback.

乔丹丽格

推荐答案

我终于可以通过加强MicrosoftAjaxWebForms.debug.js并验证了PageRequestManager确实产生后收集前提高了BeginRequest事件。更糟的是,集合被存储在一个局部变量一个StringBuilder,所以我不能操纵它,即使我愿意访问私有成员。

I finally got around to stepping through MicrosoftAjaxWebForms.debug.js and verified that the PageRequestManager does indeed generate the post collection prior to raising the beginRequest event. Worse, the collection is stored in a StringBuilder in a local variable, so I couldn't manipulate it, even if I was willing to access private members.

我找到的解决方案是从Page_Load中在code调用ScriptManager.RegisterOnSubmitStatement的背后,设置一个JavaScript beforePostback()函数。我验证了PageRequestManager开始其肮脏的工作之前,这个功能确实被调用,所以我能够把我的电话给removeNonEssentialPostBackValues​​()在那里。

The solution I found was to call ScriptManager.RegisterOnSubmitStatement from Page_Load in code behind, to setup a JavaScript beforePostback() function. I verified that this function does indeed get called before the PageRequestManager begins its dirty work, so I was able to put my calls to removeNonEssentialPostBackValues() in there.

    If Not ScriptManager.GetCurrent(Me).IsInAsyncPostBack Then
        ScriptManager.RegisterOnSubmitStatement(Me, Me.GetType(), "beforePostback", "beforePostback()")
    End If

和JavaScript的:

And the JavaScript:

function beforePostback() {
    var nlTriggers = document.getElementsByName(document.aspnetForm.__EVENTTARGET.value);
    if (nlTriggers && nlTriggers.length > 0) {
        var elPostBackTrigger = nlTriggers[0];
    }

    // skip the first input element, which is expected to be the ScriptManager's hidden field
    removeNonEssentialPostBackValues(document.aspnetForm.getElementsByTagName("input"), elPostBackTrigger, 1);
    removeNonEssentialPostBackValues(document.aspnetForm.getElementsByTagName("select"), elPostBackTrigger);
    removeNonEssentialPostBackValues(document.aspnetForm.getElementsByTagName("textarea"), elPostBackTrigger);
}

有了这个code,我发现我可以从大约34K减少我的手工制作的噩梦回传请求的大小下降到约15K。我也验证了重要形式值仍然可以通过页面传递,而code-背后仍然可以辨别哪些因素触发回发。

With this code, I found that I could reduce the size of the postback request in my hand-crafted nightmare scenario from about 34K down to about 15K. I also verified that the important form values were still getting passed through to the page, and that the code-behind could still discern which element triggered the postback.

显然,这种技术是相当严厉的,并且将不适合许多场景。例如,在一个典型的Web表单方案,其中用户必须编辑多个领域,通过验证,你不会想这样做,因为你的需求的被张贴的所有表单值。说真的,这种技术越来越接近客户端界面,JavaScript的也只最小服务器调用必要进行其命令的简单方法。我已经建立了这样的应用程序前,而他们的表现非常好,他们是乏味的开发和维护。对于这个项目,我想利用ASP​​.NET尽可能多的同时保持高性能。

Obviously, this technique is quite heavy-handed, and would not fit many scenarios. For example, in a typical web form scenario where the user must edit multiple fields and pass validation, you wouldn't want to do this, because you would need all the form values to be posted. Really, this technique is a simple way of getting closer to a client-side interface where the JavaScript makes only the minimum server calls necessary to carry out its commands. I've built such applications before and while their performance is very good, they are tedious to develop and maintain. For this project I wanted to leverage ASP.NET as much as possible while maintaining high performance.

更新:我只是在IE 8测试这(我使用Firefox 3.6了),这是一个非常缓慢的过程来禁用数百/千表单元素。花费1或2秒,不同于火狐3.6,这甚至不闪烁。我不敢想像有多慢IE 7可能。我想我将不得不放弃这一技术现在,由于引入了大量的IE用户的延迟会比对不必要的表单元素引起的回发数据的额外20K的延迟要大得多。

UPDATE: I just tested this in IE 8 (I had been using Firefox 3.6) and it is a very slow process to disable the hundreds/thousands of form elements. It takes 1 or 2 seconds, unlike Firefox 3.6, which doesn't even blink. I shudder to think how slow IE 7 might be. I guess I will have to abandon this technique for now, since the delay introduced for the large amount of IE users would be much greater than the delay caused by the extra 20K of postback data for the unnecessary form elements.

这篇关于如何禁用或ASP.NET异步回发之前删除不必要的表单元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆