Asp.net core+ Layui 项目中编辑按钮传递数据的方法

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,调用子页面预定义的全局函数或设置全局变量。

适用场景‌:逻辑较复杂,需要子页面执行特定初始化逻辑。

相关推荐
DanCheOo2 小时前
Prompt 工程化管理:从散落在代码里到版本化、可测试、可回滚
前端·ai编程
涛涛ing2 小时前
Vue 3.5 下一站:cached 提案,重新定义响应式缓存
前端
胖子不胖2 小时前
svg之viewBox
前端
吹牛不交税2 小时前
tree-transfer-vue3 前端插件安装问题解决(--legacy-peer-deps)(其他插件可考虑)适用
前端·javascript·vue.js
ricardo19732 小时前
Chrome DevTools + Lighthouse + Performance API:前端性能调优三件套实操指南
前端
Appoint_x2 小时前
设计稿自己会说话:我用 Claude 给 Figma 做了个 AI 上下文插件
前端·javascript
豹哥学前端2 小时前
浏览器console里的双中括号 `[[ ]]`
前端·javascript·ecmascript 6
菜泡泡@2 小时前
npm 安装pnpm之后运行pnpm -v查询报错
前端·npm·node.js