Asp.net core+ Layui 项目中编辑按钮传递数据的方法
将数据从父页面数据传递到弹出层(子页面/iframe)
第一种、asp.net core的传递方法

1、点击编辑后将ID传递给控制器
js
// 表格工具栏事件
table.on('tool(userTable)', function(obj){
var data = obj.data;
if (obj.event === 'edit'){
layer.open({
type: 2,
title: '编辑用户',
content: '/User/EditUser?id=' + data.id,
area: ['500px', '400px'],
end: function () {
table.reload('userTable'); // 刷新表格
}
});
}
2、在控制器中获取数据并传递给视图
csharp
/// <summary>
/// 编辑用户页面
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
public async Task<IActionResult> EditUser(int id)
{
ViewData["Title"] = "编辑用户";
var user = await _userRepository.GetByIdAsync(id);
if (user == null)
return ErrorResult("用户不存在");
return View(user);
}
3、视图通过Model 获取数据
html
@{
ViewData["Title"] = "编辑用户";
Layout = null;
}
@model PMS.Models.Entitys.User
<link href="~/layui/css/layui.css" rel="stylesheet" />
<!-- 编辑用户弹窗 -->
<div style="padding:20px;">
<form class="layui-form layui-form-pane" lay-filter="userFormFilter">
<input type="hidden" name="id" value="@Model.Id">
<div class="layui-form-item">
<label class="layui-form-label">用户名</label>
<div class="layui-input-block">
<input type="text" name="username" value="@Model.Username" required lay-verify="required" placeholder="请输入用户名" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">密码</label>
<div class="layui-input-block">
<input type="password" name="password" placeholder="请输入密码(留空不修改)" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">真实姓名</label>
<div class="layui-input-block">
<input type="text" name="realName" value="@Model.RealName" placeholder="请输入真实姓名" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">邮箱</label>
<div class="layui-input-block">
<input type="text" name="email" value="@Model.Email" placeholder="请输入邮箱" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
<input type="radio" name="isActive" value="true" title="启用" @(Model.IsActive ? "checked" : "")>
<input type="radio" name="isActive" value="false" title="停用" @(!Model.IsActive ? "checked" : "")>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="submit_EditUser">确认修改</button>
</div>
</div>
</form>
</div>
<script src="~/layui/layui.js"></script>
<script src="~/ViewScript/User/EditUser.js"></script>
4、js 获取数据并提交
js
layui.use(['form', 'layer', 'jquery'], function () {
var form = layui.form;
var $ = layui.$;
var layer = layui.layer;
// 监听表单提交
form.on('submit(submit_EditUser)', function (data) {
var field = data.field;
// 显示加载提示
var loadIndex = layer.load(1);
// 使用AJAX提交表单数据
$.ajax({
url: '/User/Update?id=' + field.id,
type: 'PUT',
contentType: 'application/json',
data: JSON.stringify({
id: parseInt(field.id),
username: field.username,
password: field.password || '',
realName: field.realName || '',
email: field.email || '',
isActive: field.isActive === 'true'
}),
success: function (res) {
layer.close(loadIndex);
if (res.code === 200) {
layer.msg(res.msg || '修改成功', { icon: 1, time: 1000 }, function () {
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
});
} else {
layer.msg(res.msg || '修改失败', { icon: 2 });
}
},
error: function () {
layer.close(loadIndex);
layer.msg('网络请求失败', { icon: 2 });
}
});
return false; // 阻止表单默认提交
});
});
第二种、Layui的传递方法
父页面
1、父页面获取所有数据
2、获取子页面iframe 的 body 对象
3、进行数据填充
4、通过回调函数,进行数据获取,并提交指定URL
js
<script>
layui.use(['table', 'layer', 'form'], function(){
var table = layui.table;
var layer = layui.layer;
var form = layui.form;
// 模拟数据
var mockData = [
{id: 1001, username: '张三', email: 'zhangsan@example.com', sex: '男', city: '北京', status: 1},
{id: 1002, username: '李四', email: 'lisi@test.com', sex: '女', city: '上海', status: 0},
{id: 1003, username: '王五', email: 'wangwu@demo.org', sex: '男', city: '广州', status: 1}
];
// 渲染表格
table.render({
elem: '#userTable',
data: mockData,
cols: [[
{field: 'id', title: 'ID', width: 80, sort: true},
{field: 'username', title: '用户名', width: 120},
{field: 'email', title: '邮箱', width: 200},
{field: 'sex', title: '性别', width: 80},
{field: 'city', title: '城市', width: 100},
{field: 'status', title: '状态', width: 100, templet: function(d){
return d.status == 1 ? '<span style="color:green">正常</span>' : '<span style="color:red">禁用</span>';
}},
{fixed: 'right', title: '操作', toolbar: '#barDemo', width: 150}
]],
page: false
});
// 监听工具条事件
table.on('tool(userTable)', function(obj){
var data = obj.data; // 获得当前行数据
var layEvent = obj.event; // 获得 lay-event 对应的值
if(layEvent === 'edit'){
editUser(data);
} else if(layEvent === 'del'){
layer.confirm('真的删除行么', function(index){
obj.del(); // 删除对应行(tr)的DOM结构
layer.close(index);
layer.msg('删除成功');
});
}
});
// 编辑用户函数
function editUser(editData){
var index = layer.open({
title: '编辑用户',
type: 2,
area: ['600px', '500px'],
fixed: false, // 不固定
maxmin: true,
content: 'edit_form.html', // 子页面路径
success: function(layero, index){
// 【关键步骤】获取 iframe 的 body 对象
var body = layer.getChildFrame('body', index);
// 【关键步骤】将父页面数据填充到子页面表单
// 注意:子页面中的 input 需要有对应的 class 或 name
body.find('.id').val(editData.id);
body.find('.username').val(editData.username);
body.find('.email').val(editData.email);
//处理单选框:找到 value 等于 editData.sex 的单选框并选中
body.find("input[name='sex'][value='"+editData.sex+"']").prop("checked", true);
//处理下拉框:设置 select 的值
body.find('.city').val(editData.city);
//处理开关/复选框等:根据状态设置
if(editData.status == 1){
body.find("input[name='status']").prop("checked", true);
} else {
body.find("input[name='status']").prop("checked", false);
}
// 【重要】获取子窗口的 layui 实例,重新渲染表单
// 因为直接修改 DOM 不会触发 Layui 的样式更新(如下拉框、单选框的美化)
var iframeWindow = window['layui-layer-iframe' + index];
// 等待子页面 layui 加载完成后渲染
// 这里使用 setTimeout 确保子页面 DOM 和 Layui 模块已就绪
setTimeout(function(){
if(iframeWindow && iframeWindow.layui){
iframeWindow.layui.form.render();
}
}, 50);
},
yes: function(index, layero){
// 点击确定按钮时的回调
var body = layer.getChildFrame('body', index);
var iframeWindow = window['layui-layer-iframe' + index];
// 触发表单提交验证(如果子页面有表单提交逻辑)
// 这里演示直接获取数据
var submitData = {
id: body.find('.id').val(),
username: body.find('.username').val(),
email: body.find('.email').val(),
sex: body.find("input[name='sex']:checked").val(),
city: body.find('.city').val(),
status: body.find("input[name='status']:checked").length > 0 ? 1 : 0
};
console.log('提交的数据:', submitData);
// 模拟 AJAX 提交
layer.msg('保存成功: ' + JSON.stringify(submitData), {icon: 1});
// 关闭弹窗
layer.close(index);
// 可选:刷新父页面表格或更新当前行数据
// obj.update(submitData); // 如果是局部更新
}
});
}
});
</script>
子页面
1、需要加载layui.form
2、每个需要填充的对象的name属性必须与数据一致
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>编辑用户表单</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="//unpkg.com/layui@2.9.8/dist/css/layui.css" rel="stylesheet">
<style>
body { padding: 20px; background-color: #fff; }
.layui-form { margin-right: 20px; }
</style>
</head>
<body>
<form class="layui-form" action="" lay-filter="editForm">
<!-- 隐藏域 ID -->
<input type="hidden" name="id" class="id">
<div class="layui-form-item">
<label class="layui-form-label">用户名</label>
<div class="layui-input-block">
<input type="text" name="username" class="layui-input username" lay-verify="required" placeholder="请输入用户名" autocomplete="off">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">邮箱</label>
<div class="layui-input-block">
<input type="text" name="email" class="layui-input email" lay-verify="email" placeholder="请输入邮箱" autocomplete="off">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">性别</label>
<div class="layui-input-block">
<input type="radio" name="sex" value="男" title="男">
<input type="radio" name="sex" value="女" title="女">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">城市</label>
<div class="layui-input-block">
<select name="city" class="city" lay-verify="required">
<option value="">请选择城市</option>
<option value="北京">北京</option>
<option value="上海">上海</option>
<option value="广州">广州</option>
<option value="深圳">深圳</option>
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
<input type="checkbox" name="status" lay-skin="switch" lay-text="正常|禁用" value="1">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<!-- 子页面通常不需要自己的提交按钮,由父层弹窗的 yes 回调控制 -->
<!-- 如果需要子页面独立提交,可以保留此按钮 -->
<!-- <button class="layui-btn" lay-submit lay-filter="formSubmit">立即提交</button> -->
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
<script src="//unpkg.com/layui@2.9.8/dist/layui.js"></script>
<script>
layui.use(['form'], function(){
var form = layui.form;
// 可以在这里初始化一些子页面特有的逻辑
// 注意:父页面已经通过 layer.getChildFrame 进行了赋值和 render()
// 所以这里不需要再次赋值,除非是动态加载的下拉选项等
// 监听子页面表单提交(如果父层不使用 yes 回调,而是让子页面自己提交)
/*
form.on('submit(formSubmit)', function(data){
console.log(data.field);
// 获取父层索引并关闭
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
return false;
});
*/
});
</script>
</body>
</html>
功能与特点
父子页面分离架构:
index.html 作为主容器,负责展示数据和触发编辑动作。
edit_form.html 作为纯表单页面,专注于 UI 展示和数据录入,降低了耦合度。
精准的数据回填:
使用了 layer.getChildFrame('body', index) 直接操作子页面 DOM。
针对不同类型的表单元素采用了不同的赋值策略:
文本框:直接使用 .val()。
单选框 (Radio):使用属性选择器 input[name='sex'][value='...'] 配合 .prop('checked', true)。
下拉框 (Select):使用 .val() 设置选中项。
开关 (Switch):根据状态设置 checkbox 的 checked 属性。
Layui 表单渲染同步:
在父页面赋值完成后,通过 window['layui-layer-iframe' + index].layui.form.render() 强制刷新子页面的表单样式。这是解决"数据赋值了但界面没变"(特别是下拉框和单选框)的关键步骤。
灵活的数据获取:
在父页面的 yes 回调中,再次通过 getChildFrame 获取子页面最新填写的值,实现了数据的闭环处理。这种方式比让子页面调用父页面方法更易于维护,因为控制权主要在父页面。
第三种、通过 URL 参数传递
在打开弹出层时,将数据拼接在 URL 后面,子页面通过解析 URL 获取参数。
适用场景:数据量较小,主要是 ID 等简单标识,或者希望子页面独立性强,不依赖父页面 DOM 操作。
第四种、通过 iframe 窗口对象直接赋值(全局变量/方法)
父页面直接访问 iframe 的 contentWindow,调用子页面预定义的全局函数或设置全局变量。
适用场景:逻辑较复杂,需要子页面执行特定初始化逻辑。