layer弹窗+ef引入独立页面进行操作
使用layer弹窗进行操作的时候我们可以使用type=2,来把一个独立的页面指向content内容
例如我们有一个表格,点击添加后,我们可以单独创建一个视图来做添加
$(".adda").click(function () { layer.open({ title: "添加", type: 2, skin: "layui-layer-molv", area: ["550px", "320px"], /*指定添加的页面*/ content: "/home/addview", yes: function () { }, btn: ["确定"] }); });
/home/addview就是一个独立的视图,里边就是放了一些输入框,以便用户输入
弹出效果如下:
其实就是生成了一个Iframe而已,所以里边的内容其实就是一个iframe。
tip:我这个界面用的是bootstrap,由于iframe是独立的页面需要相关的样式还是需要引入一下
由于我们现在添加的页面独立出来了,所以我们点击确定的时候,就需要调用添加页面里边的方法
这里的思想应该是:添加的逻辑写到添加页面里边去
而不是点击确定后把添加的信息拿到引用他的页面然后在写添加逻辑
如果把添加逻辑写到引用他的页面去主要有两个不好的地方:
1:还要把一大堆添加的数据拿回来
2:通用性就差了,如果还有一个地方要使用,添加的逻辑就要重复编写了,本来使用独立的页面写就是为了降低耦合度。面向对象三大特征之一的封装就是指的要通用的逻辑要封装起来,不要在外面在去操作了
首先看看在添加视图里边的添加逻辑
//添加的逻辑(在独立的页面里) var addway = function (success) { $.post('/home/AddUser', $("#opeform").formtojsonobj(), function (result) { success(result); }); }
这个逻辑很简单就是把表单一句话序列化成json对象,然后回传使用ef添加就行了,非常的简单方便
只是要注意一下,我这里在addway里边传递了一个方法过来,是因为添加成后我要添加引入他的页面我添加成功了
然后引用他的页面知道后才可以做后续的操作,其实就是一个使用回调函数的逻辑,这里使用回调函数逻辑会清晰很多
当然这个逻辑是写到独立页面还是外面,也不是绝对的
关键是看你像要复用的是什么,如果想要复用的仅仅是那个可以编辑的界面效果,想要添加和更新就有那个的话,当然逻辑放到外面来更好,
如果想要复用整个功能的话自然是把具体逻辑写到里边去,当然还可以分得更细一点,达到两种情况都可以复用的效果。
然后我们只需要在引用他的页面调用一个addway方法就ok了
由于是跨iframe调用,所以我们需要通过Id拿到iframe对象后在调用方法
window.frames["id"].方法
所以在我们这里就这样就可以了
window.frames["layui-layer-iframe1"].addway(function (result) { if (result > 0) { alert('添加成功'); location.href = "/home/index"; } });
layui-layer-iframe1就是弹出层iframe的那个di
完整的弹出代码如下:
$(".adda").click(function () { layer.open({ title: "添加", type: 2, skin: "layui-layer-molv", area: ["550px", "320px"], content: "/home/addview", yes: function () { window.frames["layui-layer-iframe1"].addway(function (result) { if (result > 0) { alert('添加成功'); location.href = "/home/index"; } }); }, btn: ["确定"] }); });
当然如果那个这样的弹出层有多个,iframe的id写死不好,那么使用当前layer的对象,或者id去拿吧
弹窗iframe的name和id均为"layui-layer-iframe"+Index
这里用了两个回调函数,让子页面来调用
在说一下用独立页面更新的情况:
由于是更新我们需要把以前的值传递到输入框,传值大概有两种方法:
1:只传递一个id到独立页面,在后台查询一次数据库,然后把数据返回回来
页面没有独立出来的时候就是使用的第二种,这里先说说第一种吧,在独立页面的情况下用得多一点
传递id通过路由传递即可
后台就用ef查询一下,然后model传值
public ActionResult Update(int Id) { oaEntities oae = new oaEntities(); Users users = oae.Users.Where(a => a.Id == Id).FirstOrDefault(); return View(users); }
前台就用mvc的htmlhelper显示一下即可:
<link href="~/media/css/bootstrap.min.css" rel="stylesheet" type="text/css" /> <link href="~/media/css/style.css" rel="stylesheet" /> <script src="~/media/js/jquery-1.10.1.min.js" type="text/javascript"></script> @model EFLearn.Users <div style="width: 90%; margin: 50px auto" id="updatediv"> <form id="updateform"> <div class="row-fluid"> <div class="span6"> <h4>用户</h4> <p> @Html.TextBoxFor(a => a.UserName, new { @class = "span12 m-wrap" }) </p> <h4>学号</h4> <p> @Html.TextBoxFor(a => a.Number, new { @class = "span12 m-wrap" }) </p> </div> <div class="span6"> <h4>班级</h4> <p> @Html.TextBoxFor(a => a.UClass, new { @class = "span12 m-wrap" }) </p> <h4>状态</h4> <p> @Html.DropDownListFor(a => a.CheckType, new List<SelectListItem>() { new SelectListItem(){Text="审核通过",Value="1"}, new SelectListItem(){Text="正在审核",Value="2"}, new SelectListItem(){Text="审核失败",Value="3"} }) </p> </div> </div> </form> </div>
选中状态那个如果不想用htmlhelper方式的话,直接通过js也很简单
2:不在请求后台,自己从前台获取值,然后传递到独立页面放入输入框即可
首先在独立的页面提供一个供传递参数的方法
var inject = function (obj) { $("#updateform").injectValue(obj); }
然后在layer弹出的加载完成事件中调用这个方法,把组装好的json对象传递过去即可
这里说一下injectValue方法,这个是自己封装的一个jquery插件,可以直接通过一个表单给对象赋值,就不用一个一个点出来在通过选择器去赋值了,其实原理很简单,里边就是遍历一下json对象即可,也相当于就是遍历一个键值对。
大概样子就是这样
$.fn.injectValue = function (obj) { for (var key in obj) { $("#" + key).val(obj[key]); } }
最后在说一点:
优点:代码耦合性低,功能独立写到一个页面,如果可能还可以重复利用
缺点:增加工作量,页面加载速度更慢,如果要做通用代码生成的话感觉也不是太好
所以还是业务逻辑复杂一点,功能多一点的操作单独提出来写吧,显得逼格都要高一点
吃饭啦,吃饭啦