利用layer实现MVC页面数据互交提示弹框

需求说明:css

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

应用场景:jquery

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

前期准备:浏览器

实现过程:dom

  首先,来一段最原始简单的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="width: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):post

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

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

 

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

首先进入第一个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提交,验证插件就彻底失效了,这还只是最初步的实验,估计那些看得见的看不见的问题会更多,

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

相关文章
相关标签/搜索