Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 680|回复: 0

使用ASP.NET AJAX与Bootstrap 弹窗解决方案

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-4-11 11:33:53 | 显示全部楼层 |阅读模式

    我在做采购系统时,因为使用了ASP.NET AJAX的UpdatePanel的控件,可以使得页面局部刷新显示。但是使用起来问题还是很多。

    下面列出了一种情况,花了将近5个小时才算解决,虽然不是很完美,但是对于一般应用应该够了。

    应用背景:在采购系统里,因为一个产品可以有多个供应商,同样一个供应商可以有多个产品。所以产品和供应商是多对多的关系。

    在产品页面,用户选择一个产品,我们希望他可以选择供应商。如下图,选择“得利纸业”,然后在单击“关联供应商”,就弹出供应商页面,让用户选择供应商。

     

     

    其实,如果是采用刷新技术,这种功能很好实现。让父页面刷新一下,解决方法还是非常简单的。常规的解决方法大都是用 window.open()弹出子页面,

    然后在子页面关闭时,刷新父页面就完成了。但是,因为父页面全刷新,用户体验非常差。

     

     

    刚开始,我感觉问题很简单,bootstrap有model模板(详见 http://v3.bootcss.com/javascript/) ,代码类似如下

      <a href="#" class="btn btn-sm  bg-green btn-flat"    data-toggle="modal" data-target=".bs-example-modal-lg">关联供应商</a>
    

     用户单击关联供应商时,弹出在产品列表页面的一个层。(注意:是层,所以这里没有父-子页面,为的就是局部刷新),代码类似如下

      <asp:UpdatePanel ID="UpdatePanel5" runat="server">
                            <ContentTemplate>
    
    <div class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
     
    
                   <asp:linkbutton Text="分类A" runat=server id="c1" />
                   <asp:linkbutton Text="分类B" runat=server id="c21" /> 
                  
    
                  <asp:gridview runat="server" id="prod"></asp:gridview> 
     
           
               <asp:Button ID="btn_connection_supply"  runat="server" Text="关联供应商" OnClick="btn_connection_supply_Click" />
                
            </div> 
     
        </div> 
    
                            </ContentTemplate>
    
                        </asp:UpdatePanel>
    

     

    弹出的层,放到UpdatePanel里,在UpdatePanel,左边是ASP.NET LinkButton显示分类名称,右边是GridView显示分类结果,下部一个Button,单击“关联供应商”,

    感觉很完美。但是实际测试,问题来了。当用户单击左边分类名称时,白色弹框消失了,用户根本没有时间选择右边的商户列表,更麻烦的是白色消失后,弹出的阴影背景还在,整个页面像死在那里了。只有重新刷新页面。

     

    问题出现了,就开始想办法解决。首先想,用户单击左边Linkbutton,因为是异步回发,最简单的方式,是在回发回来时,仍然让白色的供应商页面显示。查了一下Bootstrap,发现有函数

    Bootstrap提供了show函数,可以显示调用,让弹窗显示。

    因此,我在LinkButton里,调用了此方法,代码类似如下

         ScriptManager.RegisterStartupScript(button, typeof(LinkButton),
                     "init", "$(".pop").show(true);", true);
    

     很奇怪,跟踪了返回解决,发现虽然服务器执行了,客户端没有执行。我记得我在做日志系统时,这个代码是执行了,唯一的区别是:

    在采购系统里,我将UpdatePanel的  ChildrenAsTriggers设置为"False"  UpdateMode设置"Conditional" ,为的就是不让子刷新时,父跟着刷新。

    看了Bootstrap无法解决了,只能够通过ScriptManager解决, Sys.WebForms.PageRequestManager提供了一系列的Request客户端页面生命周期,详见

    https://msdn.microsoft.com/zh-cn/library/bb311028.aspx

    所以,我在LinkButton的返回时,执行endRequest

         var prm = Sys.WebForms.PageRequestManager.getInstance(); 
                prm.add_endRequest(function () {
                  $(".model").show(true)
                }); 
    

     然而,这种情况得到了相反的结果,白色页面关不掉了。正常情况下,用户在单击“确认管理供应商”时,页面就应该关闭,现在又关不掉了。

    看来,我还要区分endrequest的请类似,其另外一种方法是:应该可以判断用户提交的Button类型。函数原型如下. 其实这里还有一个问题没有解决,如果GridView供应商分页,同样单击上一页,下一页,也会出现这个问题。看来问题越来越多。

    var prm = Sys.WebForms.PageRequestManager.getInstance(); 
                prm.add_endRequest(function (send,arg) {
                  $(".model").show(true)
                }); 
    

     此时,我已经精疲力尽,算了,不做了,去吃饭了。

     吃过饭后,突然想出来一个方法:为什么要服务器分页,不是有JS 的DataTable,以前用过他,他本身就可以客户端分页啊。

    http://www.datatables.net/ 看一下演示(注:DataTable默认使用Google提供Jquery CDN,因为大陆屏蔽了Google,所以演示站点无法打开,可以在Host里增加配置解决。)

    dataTable默认提供客户端分页,只要table增加一个id,就可以自动分页,排序,模糊查询

     $('#tbl_supply2').DataTable(
                     { 
                     }
                    )
    

     可是DataTable,就在我认为已经好的时候,问题又来了。再我测试时,选择了产品,单击“关联供应商”时,系统调用  $('#tbl_supply2').DataTable() 。但是可能用户没做任何操作关闭了弹窗,又再次单击了“关联供应商”。

    此处会出现一个错误“DataTable已经被初始化”。原来用户第一次单击关联供应商时,DataTable进行了初始化。再次单击时,因为已经初始化了,所以会出错。这个问题解决起来会比较简单,只要在document.Ready()里进行进行初始化就可以了。经过测试发现,因为在产品列表里,也用了AJAX,在异步回发时,页面结构已经改变,所以Ready()事件里执行会有问题。

    赶快看看DataTable的接口。后来在其API里提供里找到了相关介绍 http://datatables.net/reference/option/destroy 可以利用其destroy参数

    代码只要更改为: 

    $('#tbl_supply2').DataTable(
                     {
    destroy: true 
                     }
                    )

    就可以了。
    因此,最后的函数如下:增加了Ordering参数,禁止排序,lengthMenu设置分页为5或者10。

     function pageSupply() {
               
                $('#tbl_supply2').DataTable(
    
                     {
                         destroy: true,
                         "ordering": false,
                         "info": false,
                         "lengthMenu": [5, 10]
                     }
                    )
            };


    最后的页面就是完成的页面 可以去演示  http://demo.dotnetcms.org/purchase/ 查看。 另外,说说不完美的,因为是客户端分页,所以大量数据可能会影响性能。

    以前给一个客户端,他们有2000多个用户列表使用DataTable分页,用户打开时,2000多行分页经常会卡。不过,在采购系统里,应该不会有2000个供应商,对于应付一二百个

    供应商,DataTable 客户端分页排序,还是绰绰有余的。

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-22 17:16 , Processed in 0.067886 second(s), 27 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表