zoukankan      html  css  js  c++  java
  • 利用layer实现MVC页面数据互交提示弹框

    需求说明:

      一个表单页面,点击提交之后,进入后台进行一系列数据交互,然后将交互信息返回至页面中,并以弹框形式展示

    应用场景:

      添加、修改、删除数据后,返回数据操作是否成功,以及一些其他信息

    前期准备:

    实现过程:

      首先,来一段最原始简单的HTML和后台代码,请忽略CSS

     1 <html>
     2 <head>
     3     <title>Default</title>
     4     <!-- CSS文件引用 -->
     5     <link href="/Content/Script/Plug/layui/css/layui.css" rel="stylesheet">
     6 </head>
     7 <body>
     8 
     9     <form action="/Home/Default" method="post" class="layui-form" style="80%;margin:0px auto;">
    10         <fieldset>
    11             <legend>表单</legend>
    12             <!-- 输入框 -->
    13             <div class="layui-form-item">
    14                 <label class="layui-form-label">输入框</label>
    15                 <div class="layui-input-block">
    16                     <input type="text" name="title" placeholder="请输入文字" class="layui-input">
    17                 </div>
    18             </div>
    19             <!-- 提交按扭 -->
    20             <div class="layui-form-item">
    21                 <div class="layui-input-block">
    22                     <input type="submit" class="layui-btn layui-btn-block">
    23                 </div>
    24             </div>
    25 
    26         </fieldset>
    27     </form>
    28     <!-- JS文件引用 -->
    29     <script src="/Content/Script/jquery-3.2.1.min.js"></script>
    30     <script src="/Content/Script/Plug/layui/layui.all.js"></script>
    31 
    32 </body>
    33 </html>

    效果如下(图1):

     紧接着,是一段简单的后台代码:

     1         public ActionResult Default() {
     2 
     3             return View();
     4         }
     5 
     6         [HttpPost]
     7         public ActionResult Default(string title) {
     8 
     9             return View();
    10         }

    代码的执行过程是这样的,

    首先进入第一个Defult()方法,简称Get方法,展示页面

    在页面中,点击表单的提交按钮,会进入第二个Gefult()方法,简称Post方法,进行数据处理,然后返回页面

    Get方法可以暂时忽略,它和返回弹框信息并没有什么关系,我们主要是对Post方法进行改造

    要实现弹框效果,其实很简单,略微改造就OK:

    1         [HttpPost]
    2         public ActionResult Default(string title) {
    3 
    4             return Content("<script>alert('" + title + "')</script >");
    5         }

     但这样的效果非常不友好,非常难看不说,每个浏览器alert出来的弹框样式都不一致,而且,还有这样那样的bug,效果如图(图2):

    根据layui的文档,layer.msg("msg");执行的弹框还是非常不错的,那我们就将alert修改为layer.msg();:

    1         [HttpPost]
    2         public ActionResult Default(string title) {
    3 
    4             return Content("<script>layer.msg('" + title + "')</script >");
    5         }

    然后,执行就炸毛了,弹框没有出现,页面也是一片空白:

    可以看到,拼接出来的script代码并没有问题,然而控制台却报错:Default:1 Uncaught ReferenceError: layer is not defined,没找到layer对象

    这是什么原因呢??再看当前页面的HTML:

    只有一些最基本的标签,以及head里面一个孤零零的script代码,这样错误就很明显了,

    layer.msg();这个方法是要依赖于layui.js的,现在还没有引用文件,自然会报错,

     那么,问题又来了,为什么返回的视图只有一段script代码呢??

    仔细观察,不难发现,比较原始代码当前代码,最大的不同是return 的内容不一样了,

    原始代码:return View();// 返回当前视图对应的html代码

    当前代码:return Content("");// 返回传入的字符串

    现在问题就很明了了,

    如果我要返回页面的话,肯定是要返回View()的,那里面有需要的各种文件的引用,

      然后在返回View();的情况下,返回字符串,如果不考虑使用ViewBag,因为总感觉用那个的非常不方便,那么我们只能使用View("Msg");来返回信息

      这样的话,如果我要对页面返回一个实例对象,就又呵呵了,所以,使用View();返回的方法不作考虑

    那么就只能使用Content();方法返回信息了,

      其实页面信息不显示的问题还是很好解决的,可以这样返回:return Content("<script>location.htrf='/Home/Default';</script>");

      利用js进行页面跳转,就会跳转至Get方法,而Get方法是return View();所以页面信息显示的问题解决了,

      但是,如何弹框呢?

      如果将弹框代码layer.msg("Msg");写在跳转之前,那个时候还没有引用文件,所以肯定是报错,无法弹框的,说不定还会因为报错导致跳转代码无法执行,所以pass,

      若写在跳转之后,嗯,页面已经跳转了,你这个弹框先不说能不能弹出来,哪怕弹出来也看不到了,毕竟已经跳转到另外一个页面了,

      很好,现在局面又陷入了僵局,,,

      想想,现在我们应该怎么处理???

      能不能让跳转和弹框分开,既然它们相看两厌,那就让它们互不相关,互不影响怎么样,你跳你的页面,我弹我的框,咱们画好三八线

      那么,这根三八线怎么画,用什么画??答案是iframe

      新建一个页面Index,该引用的引用好,然后将页面Default嵌入到iframe中,

      这样跳转的话,只是iframe跳转,而我的弹框,完全可以跳出Default文件引用的约束,利用父窗Index的引用实现

    具体实现过程如下:

    新建一个父窗的后台和HTML:

    1         public ActionResult Index() {
    2 
    3             return View();
    4         }
     1 @{
     2     Layout = null;
     3 }
     4 
     5 <!DOCTYPE html>
     6 
     7 <html>
     8 <head>
     9     <meta name="viewport" content="width=device-width" />
    10     <title>@ViewBag.Title</title>
    11     <!-- CSS文件引用 -->
    12     <link href="~/Content/Script/Plug/layui/css/layui.css" rel="stylesheet" />
    13     <!-- JS文件引用 -->
    14     <script src="~/Content/Script/jquery-3.2.1.min.js"></script>
    15     <script src="~/Content/Script/Plug/layui/layui.all.js"></script>
    16 </head>
    17 <body>
    18     <script>
    19 
    20         $(function () {
    21             // 创建iframe
    22             layer.open({
    23             type: 2,// 2为iframe
    24             title: false,// 去掉标题
    25             closeBtn: 0,// 去掉关闭按钮
    26             shade: false,// 关闭遮罩层
    27             maxmin: false, // 关闭最大化最小化按钮
    28             area: ['100%', '100%'],// 直接最大化,充当Index内容
    29             anim:5,// 渐变出现
    30             content: '@Url.Action("Default", "Home")'// iframe链接地址
    31             });
    32         });
    33         
    34     </script>
    35 </body>
    36 </html>

    这样运行出来的效果和图1是一毛一样的,但是仔细观察,会发现它们的路径是不一样的,

    图1的路径是http://localhost:50082/Home/Default,现在运行出来的路径是http://localhost:50082/Home/Index

    这时候,就已经将Default页面用iframe嵌入Index页面了,而且毫无违和感,修改anim属性,还能有一些意外的进入动画效果,相当不错来着,,

    接下来就是返回消息弹框了,我已经封装好了,直接贴代码:

     1         [HttpPost]
     2         public ActionResult Default(string title) {
     3             return Content(LayerMsg(title));
     4         }
     5 
     6         /// <summary>
     7         /// 返回页面消息弹框
     8         /// </summary>
     9         /// <param name="msg">消息内容</param>
    10         /// <param name="url">跳转链接</param>
    11         /// <param name="icon">消息类型,[-1,6]</param>
    12         /// <param name="anim">消息动画,[-1,6]</param>
    13         /// <param name="time">出现时间,(单位:ms)</param>
    14         /// <returns></returns>
    15         public string LayerMsg(string msg, string url = "", int? icon=null, int anim = -1, int time = 2000) {
    16 
    17             // 链接,若为空,返回当前页面
    18             if (string.IsNullOrEmpty(url))
    19                 url = HttpContext.Current.Request.RawUrl;
    20             // 动画
    21             anim = anim % 7;
    22             if (anim < 0)
    23                 anim = new Random().Next(0, 7);
    24 
    25             StringBuilder str = new StringBuilder();
    26 
    27             object[] key = { "anim", "time", "icon" };
    28             object[] val = {  anim, time, icon };
    29 
    30             str.Append("<script>");
    31             str.Append("location.href='" + url + "'; ");
    32             // 由于要返回的是父窗的方法,所以加上'parent.'
    33             str.Append("parent.layer.msg('" + msg + "',{");
    34             str.Append(MosaicKeyVal(key, val) + "});");
    35             str.Append("</script>");
    36 
    37             return str.ToString();
    38         }
    39 
    40         /// <summary>
    41         /// 拼接键值对
    42         /// </summary>
    43         /// <param name="key"></param>
    44         /// <param name="val"></param>
    45         /// <returns></returns>
    46         public string MosaicKeyVal(object[] key, object[] val) {
    47             if (key.Length != val.Length)
    48                 return "";
    49 
    50             StringBuilder str = new StringBuilder();
    51             for (int i = 0; i < key.Length; i++) {
    52                 if (string.IsNullOrEmpty(key[i] + ""))
    53                     continue;
    54                 if (string.IsNullOrEmpty(val[i] + ""))
    55                     continue;
    56                 // 添加逗号
    57                 if (str.Length > 0)
    58                     str.Append(",");
    59                 // 添加键值对
    60                 str.Append(string.Format(" '{0}':'{1}'  ", key[i].ToString(), val[i].ToString()));
    61             }
    62             return str.ToString(); ;
    63         }

      效果以及返回的script代码如图:

    至此就大功告成了,那几个参数大家可以看着传过去玩玩,有惊喜的,

    尚待思考:

      有人对这个方法提出了一个需求,就是点击提交之后,不仅可以弹框,还要保证文本框里面的信息不会丢失,

      对于这个需求我表示相当无奈,除非使用ViewBag,还没有比较好的解决方法,或许是我的思路还不够开阔吧,

      那货说可以监听所有的onsubmit事件,将submit提交更改为ajax异步,这样数据就能保留下来了,而且,弹框也更简单了,直接使用success事件就好,

      但是这样总感觉哪里不对劲,也尝试这样写过,确实能够实现最开始的需求,不过会顺带出一大堆的问题,

      比如说,我加入表单验证插件Validform之后,用ajax提交,验证插件就完全失效了,这还只是最初步的实验,估计那些看得见的看不见的问题会更多,

      哪位大佬有更好的解决思路,,欢迎指点

  • 相关阅读:
    js动态创建table表格的四种方法和性能测试(转载)
    render用法汇总(转载)
    echarts 解决 X轴与Y轴数据不对应问题;X轴日期显示顺序错误问题
    数组对象按时间字符串排序(转载)
    SQL Server 取日期时间部分(转载)
    iview Table行编辑、单元格编辑(转载)
    使用C#创建Windows服务
    马士兵-synchronized
    小程序登录笔记
    Prometheus+Grafana 的方法监控 Springboot 应用
  • 原文地址:https://www.cnblogs.com/Onlooker/p/7672512.html
Copyright © 2011-2022 走看看