Flask+LayUI开发手记(一):LayUI表格的前端数据分页展现
用数据表格table展示系统数据,是LayUI的基本功能,编码十分简单,就是通过table.render()渲染,把属性配置好就OK了,十分方便,功能也十分强大。
不过,在实现时,把table的有个功能却理解错了,就是分页。
table.render()的分页属性,主要包括三个,page、limit和limits,page是逻辑值,设置为true是分页,limit是每页显示行数,limits是设置面显示行数的多条选项。应该说,这几个属性都十分清晰,按说明配好后,果然分页控制栏就显示出来了,真不错。
原来以为只要在服务端把需要的数据生成好传到前端来,分页就算完成了,但做了一段时间就发现不对了。开始做无外乎就是用户、角色、权限编辑,记录都很少,用不上分页,等做日志显示时一下就看出错误了,分页设的16条,怎么系统在一个页面把全部100多条数据都展示了。
然后仔细研究才发现,这三个分页属性设置好,只是相当于打了了前端控制的开关,界面上显示出分页流程控件,可以进行分页切换操作,但数据展示内容,前端不管,还是要后端做处理的。table会在每次点击一次页面切换时,就向后端提交一次数据请求,请求中含有page和limit属性,后端按这两个参数把当前页的数据记录生成传下来。
我是一直不喜欢这种每换一次页就要向后端提数据请求的实现逻辑的。一页才展示10几条记录,每次换页都要去取数据,来来回回的,性能不好,对后端压力有些太多了。而且,大部分数据展示功能,总共也就是几百条数据,完全可以一次把数据取到前端来,只在前端做处理就可以了。这样无疑大大减轻后端服务器的压力,而且控制上也比较简单是吧。
也因此,我把系统需要进行分页展示的功能分成两种模式实现,一是前端数据分页,二是后端数据分页 。前端数据分页,即一次性提取后台数据到前端,由前端实现全部的分页数据处理控制,后端数据分页,即前端展示分页操作栏,所有的分页操作均提交到后端进行数据请求,由后端生成分页数据传给前端。
下面这些程序,就是前端数据分页功能的实现,程序主要分为三个部分,前端html、JS实现、后端数据处理服务。
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"><title>CMS系统-登录日展示</title><link rel="stylesheet" href="/static/layui/css/layui.css" media="all">
</head>
<body><table id="admin_log" lay-filter="admin_log" style="margin-top:-15px;"></table><script type="text/html" id="toolBar"><div class="layui-btn-container"><div class="layui-inline" style="display:inline;margin-right:10px;"><label class="layui-btn-sm">日期范围</label><div class="layui-input-inline"><input type="text" id="bdate" placeholder="开始日期" autocomplete="off" class="layui-input layui-btn-sm"></div><label class="layui-btn-sm" style="display:inline;">-</label><div class="layui-input-inline"><input type="text" id="edate" placeholder="结束日期" autocomplete="off" class="layui-input layui-btn-sm"></div><div class="layui-input-inline" style="padding-left:10px;padding-top:8px"><button id="btn_search" type="button" class="layui-btn layui-btn-normal layui-btn-sm" lay-event="search"><i class="layui-icon layui-icon-search"></i>查询</button></div></div></div>
</script>
<script type="text/html" id="linetoolBar"><a lay-event="detail" title="查看细节" ><i class="layui-icon layui-icon-form"></i></a>
</script></body>
</html>
前端 HTML页面相当简单,包括三个部分,table、toolBar、linetoolBar。table部分定义了一个总的表格容器,其具体内容由table.render进行渲染。toolBar是数据表格的头部工具栏,linetoolBar是数据表格的行工具栏内容。这三部分有了,基本的展示框架也就出来了。
具体的还要看JavaScript中的处理,程序如下:
<script src="/static/layui/layui.js"></script>
<script>
layui.use(['jquery','layer','table','laydate'], function(){var $=layui.jquery,layer=layui.layer,table=layui.table,laydate = layui.laydate;var recData = null;var recCount = null;initTableData(0);// op 操作标志 0:渲染 1:重载function initTableData(op) {$.post('{{url_for("sysadm.admin_log")}}',{bdate:$('#bdate').val(),edate:$('#edate').val()},function(rs){if(rs.code == 0){recData = rs.data;recCount = rs.count;if (op ==0) table_render();else table_reload(1);layer.msg(rs.msg,function(){});}else{layer.msg(rs.msg,function(){});return false;}},'json');}function table_render() {table.render({elem: '#admin_log',height: 'full',data: recData,toolbar: '#toolBar',method: 'POST',page: true //开启分页,limits: [16, 20, 30, 40, 50] ,limit : 16 ,even : true,size : 'sm' ,cols: [[ { type: 'checkbox', fixed: 'left' },{field: 'id', title: 'ID', width:40, sort: true, fixed: 'left'},{field: 'opr_cd', title: '操作', width:40, fixed: 'left'},{field: 'operate', title: '内容', width:260},{field: 'username', title: '操作员', width:80, sort: true},{field: 'ip', title: '客户端IP', width:80},{field: 'add_time', title: '操作时间', width: 220},{fixed: 'right', width:200, align:'center', toolbar: '#linetoolBar'}]]});b_date = laydate.render({elem: '#bdate'});e_date = laydate.render({elem: '#edate'});//表头工具栏事件table.on('toolbar(admin_log)', function (obj) {switch (obj.event) {case 'search':initTableData(1);break;};});//table行内工具栏事件table.on('tool(admin_log)', function (obj) { //obj是指这张表中的数据row = obj.data; //将这张表中的数据赋给row这个变量rid = row.id;switch(obj.event) {case 'detail':adminlog_detail("查看细节",rid);break;}});}function adminlog_detail(title,rid){url = '{{url_for("sysadm.admin_log_detail",id="")}}' + rid;layer.open({type: 2, //layer提供了5种层类型。可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层)title:title,area: ['660px', '460px'], //宽高skin: 'layui-layer-rim', //样式类名content: url, //查看细节页面btn:['关闭'],yes: function(index, layero){layer.closeAll();},});}function table_reload(cpage) {table.reload('admin_log', {data : recData,page: { curr: cpage },},true);}});</script>
在数据分页展示中,最主要的思路是先把数据一次性传到前端,之后,前端进行分页展示处理。所以,处理包括三个阶段,第一、数据获取,第二、渲染数据表格,第三、数据检索并重载。
第一步数据获取,是向后端发post请求获取数据下传,这个服务器的python程序不用改动,继续按规定格式下发全量数据。
第二步渲染数据表格,这块与原来最大的区别是数据源配置发生了变化。LayUI数据表格的数据源有两种模式,一是配url属性,二是配data属性。一般实现都是配url属性,从后端路由或者是JSON文件中取数据。data方式,我只用过一次,就是调试render时,模拟生成了几条数据,配在前端变量里作为数据源。这样调试可以避免前后端通讯的干扰因素,先熟悉table的各种技术细节。好在已经用过了,要做前端分页控制,就得用data数据源模式(主要还是借鉴网上别人的经验),将后端传下来的数据结构中的data赋给前端变量,然后配置成数据源,一切OK。
这一步还出现了个小问题。开始,我把第一步数据获取initTableData()和第二步表格渲染table_render(),以串行模式编排的,也就是先取数赋本地变量再渲染表格。但运行时界面却不显示表格内容,调试发现recData变量在initTableData中有数,但在table_render渲染时居然是空值,按照程序流程不该如此呀。上网查了一下,原来是post异步通讯闹的怪,也就是说执行post后流程并不会等待结果返回,而是接着往下执行后面的程序。
先获取数据再表格渲染,这一流程必须是串行的,所以post异步通讯的处理方法必须改,必须能串行。改可以有两种方法,第一种是将post改为同步通讯,也就是程序流程阻塞在这个点,等接收到数据返回后再往下执行,但post没有设置同步的属性,要改就要改为ajax提交,这个倒也不难。不过,还有更好的办法,还是把表格渲染的程序放到post的成功后回调函数中来执行,这一样可以实行同步顺序的功能。应该说,第二种方法更简单更方便。
表格渲染,除了表格渲染render外,还要对头部及行内工具栏的按钮动作进行功能设置,这两个设置必须在表格渲染之后完成,同样属于表格渲染的一部分。合并在一起形成table_render(),都在获取数据后一起执行。
把这些都配置完成,执行一下,数据展示出来了。而且,data数据源模式下,table会自动完成分页展示控制,不需要再象url数据源模式下,还需要各种特殊处理了。这是真方便。
第三步是表格检查重载。头部工具栏中有一个检索功能,就是输入启始日期和终止日期,作为登录日志的查询条件。检索按钮实际上相当于表格数据初始化的再次重入,所以,执行了与第一次数据初始化同样的函数,只是入口属性设置为1。这时,需要从后端重新获取数据,但前端不必重新渲染,只要调用table_reload()进行重载就可以。
前端的功能完成了,下面就是后端程序了。
@bp.route('/admin_log/',methods=['GET','POST'])
@login_required
#@admin_auth
def admin_log():if request.method == 'GET':return render_template('admin/admin_log.html.j2')else :logging.debug('Admin Log POST....')bdate = request.values.get('bdate');edate = request.values.get('edate')filtstr = '1=1 'if bdate :filtstr += ' and add_time >= "' + bdate +'"'if edate :filtstr += ' and add_time <= "' + edate + '"'logging.debug('filter : ' + filtstr)adminlog = db.session.query(Admin_Log).filter(text(filtstr)).order_by(Admin_Log.add_time.desc()).all()rnum = len(adminlog)alist = []for ilog in adminlog:rdata = dict(id=ilog.id,opr_cd=ilog.opr_cd,admin_id=ilog.admin_id,username=ilog.username,operate = ilog.operate,ip=ilog.ip,add_time=ilog.add_time.strftime('%Y-%m-%d %H:%M:%S'))alist.append(rdata)rsdata = {"code": 0,"msg": "查询登录日志数据成功","count": rnum,"data":alist}return jsonify(rsdata)@bp.route('/admin_log_detail/',methods=['GET'])
def admin_log_detail():if request.method == 'GET':rid= request.values.get('id')if rid == None:return render_template('admin/admin_log_dtl.html.j2')else:ilog = db.session.query(Admin_Log).filter_by(id=rid).first()rdata = dict(id=ilog.id,opr_cd=ilog.opr_cd,admin_id=ilog.admin_id,username=ilog.username,operate = ilog.operate,ip=ilog.ip,add_time=ilog.add_time.strftime('%Y-%m-%d %H:%M:%S'))rsdata = {"success": 1,"msg": "取登录日志数据成功" + rid,"data":rdata}logging.debug(str(rsdata))return render_template('admin/admin_log_dtl.html.j2',rsdata=rsdata)
后端数据处理就是遵循flask的标准规范了,在get请求时,调用admin_log.html进行渲染,然后页面的JS程序会向后端发出post请求获取数据。后端在POST分支里取数并生成回传数据文件。回传数据文件的按规定组成,包括四部分code、count、msg和data。这个处理比较标准,不再细述了。
最后的展示样式如下
后端一次获取数据传到前端,由前端独立完成数据处理,其实只适合数据查询的应用场景。因为,一次把数据全传到前端的模式,意味着系统内出现两套数据,一套前端缓冲数据,一套后端原本数据,如果功能中需要增删改数据,如何保持前后端数据的一致性,就成了控制上的大问题。当然这种场景也是应用很广泛,专门做个前端数据分页模式也有很大用处。
但后端数据分页模式也是有很多场景应用的。比如增删改查功能,与其却考虑前后端数据同步,还不如每次切换页就向服务端请求数据简单直接,系统所有处理都只去管理后端数据即可。应该说后端数据分页的模式,应用范围更为广泛,而且程序操作流程及逻辑都比前端分页更为清晰,也是layUI table主推的模式。
相关文章:

Flask+LayUI开发手记(一):LayUI表格的前端数据分页展现
用数据表格table展示系统数据,是LayUI的基本功能,编码十分简单,就是通过table.render()渲染,把属性配置好就OK了,十分方便,功能也十分强大。 不过,在实现时,把table的有个功能却理解…...

Vulnhub靶场DC-9练习
目录 0x00 准备0x01 主机信息收集0x02 站点信息收集0x03 漏洞查找与利用1. 发现SQL注入点2. Sqlmap跑数据3. 文件包含4. SSH爆破端口敲门服务5. 提权(写入/etc/passwd) 0x04 总结 0x00 准备 下载链接:https://download.vulnhub.com/dc/DC-9.z…...

Java对象内存布局和对象头
文章目录 面试题Object object new Object() 谈谈你对这句话的理解? 对象在堆内存中存储布局权威定义(周志明老师JVM第三版)对象在堆内存中的存储布局详解对象头的MarkWord源码对象标记源码 对象内存布局(使用JOL证明)…...

python:基于YOLO框架和遥感图像的目标检测
作者:CSDN _养乐多_ 本文将介绍如何通过YOLO框架和遥感图像进行目标检测的代码。 文章目录 一、数据集下载与格式转换1.1 NWPU VHR-10(73.1 MB)1.2 DIOR(7.06 GB)1.3 配置data.yaml 二、训练三、训练结果 一、数据集…...

DAMA学习笔记(十一)-元数据管理
1.引言 元数据最常见的定义是“关于数据的数据”。它描述了数据本身(如数据库、数据元素、数据模型),数据表示的概念(如业务流程、应用系统、软件代码、技术基础设施),数据与概念之间的联系(关系…...
密码学基本理论
密码学是研究信息安全保护的科学,实现信息的保密性、完整性、可用性以及抗抵赖性 根据密码分析者在破译时已经具备的前提条件,密码分析攻击类型分类: 唯密文攻击:已知密文;未知明文+秘钥已知明文攻击:已知部分明文和密文对;未知秘钥+算法选择明文攻击:已知明文+算法--…...
【深度学习】【语音TTS】vits 论文,Variational Inference Text-to-Speech(1)
代码:https://github.com/jaywalnut310/vits 论文:https://arxiv.org/abs/2106.06103 文章目录 摘要1. 引言2. 方法2.1. 变分推理2.1.1. 概述2.1.2. 重构损失2.1.3. KL散度2.2. 对齐估计2.2.1. 单调对齐搜索2.2.2. 从文本预测时长2.3. 对抗训练2.4. 最终损失2.5. 模型架构2.5…...
javascript中 window 相关知识点以及代码演示
一.了解window 在JavaScript中,window对象是浏览器的全局对象,它不仅代表了浏览器窗口,同时也充当了ECMAScript中的Global对象的角色。因此,深入了解和掌握window对象的属性和方法对于JavaScript开发者来说至关重要。 以下内容将…...

企业社会责任(CSR)国际标准有哪些?
以下是一些常见的企业社会责任(CSR)国际标准和相关体系等: 原则性、指南性标准 ISO 26000《社会责任指南》 :将社会责任归纳为7个核心方面,即公司治理、人权、劳工、环境、公平运营实践、消费者问题以及对社会发展作贡…...
The C programming language (second edition,KR) exercise(CHAPTER 7)
E x c e r c i s e 7 − 1 Excercise\quad 7-1 Excercise7−1: #include <stdio.h> #include <string.h> #include <ctype.h>enum type {LOWER, UPPER };int main(int argc, char *argv[]) {int c, mode = -1;if (stricmp(*argv, "lower.exe") =…...

面向服务架构(SOA)介绍
在汽车电子电气架构还处于分布式时代时,汽车软件的开发方式主要是采用嵌入式软件进行开发,而随着汽车智能化程度的加深,更加复杂且多样的功能需求让汽车软件在复杂度上再上一层。在整车的自动驾驶方面,由于未来高阶自动驾驶能力的…...
关于使用Next遇到的一些新特性
用next之后发现,这是作为全栈比较好用的框架 API 1、app Router 这是目前next官方以及未来推荐的新技术方向 若使用api路由用来管理后端api接口 (1)此时在app文件夹下创建 api名称目录(如 getApiKey) (…...

Python 爬虫入门(七):requests 库的使用「详细介绍」
Python 爬虫入门(七):requests 库的使用「详细介绍」 前言1. 初识 requests1.1 安装 requests 库1.2 发送 GET 请求1.3 发送 POST 请求 2. HTTP 请求详解2.1 请求方法2.2 请求头2.3 请求参数 3. 处理响应3.1 响应内容3.2 响应状态码3.3 响应头…...
两端约束的最优控制问题及其数值解法
问题的基本形式 设 n n n维系统状态房产 x ˙ ( t ) f [ x ( t ) , u ( t ) , t ] \dot{x}(t)f[x(t),u(t),t] x˙(t)f[x(t),u(t),t],控制向量 u ( t ) ∈ Ω u(t)\in\Omega u(t)∈Ω是分段连续函数, Ω ∈ R m \Omega\in R^m Ω∈Rm是有界闭集…...

电磁仿真--基本操作-CST-(6)-导线周围磁场
目录 1. 简介 2. 过程 2.1 新建工程 2.2 选择求解器 2.3 设置单位 2.4 设置频率 2.5 绘制导线 2.6 Background 2.7 边界条件 2.8 设置激励源 2.9 查看结果 3. 其他设置 3.1 网格类型 3.2 集总网络元件 3.3 阻抗和导纳矩阵 3.4 自适应网格细化 3.4 提升计算效率…...

用Java手写jvm之模拟方法调用指令invokexxx和方法返回指令xreturn
写在前面 源码 。 本文一起看下方法调用相关的指令invokexxx以及方法返回(栈帧弹出线程栈)相关的指令xReturn 。 1:正文 因为invokexxx指令和普通的指令不同,会创建一个新的栈帧,并压倒操作数栈中,所以我…...
自定义枚举类型检查
/*** 工单状态,使用字典:order_item_state*/ CheckEnum(nullAble true, enumType OrderItemStateEnum.class) private String workState; 注解类 package com.gdyunst.core.tool.validation;import javax.validation.Constraint; import javax.valid…...

探索四川财谷通抖音小店:安全与信赖的购物新体验
在数字经济蓬勃发展的今天,抖音平台凭借其庞大的用户基础和强大的内容生态,逐渐成为了电商领域的一股不可忽视的力量。其中,四川财谷通抖音小店作为这一浪潮中的佼佼者,不仅以其丰富的商品种类和独特的品牌魅力吸引了众多消费者的…...

systemd-manage系统服务图形化管理工具使用教程
1. systemd-manage介绍 systemd-manage是一个开源的基于systemd服务管理的图形化工具,使用qt图形库进行开发,可以提供服务管理,用户会话,配置文件修改,日志查询,性能分析,进程管理等功能。图形…...
移除元素(LeetCode)
题目 给你一个数组 和一个值 ,你需要 原地 移除所有数值等于 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 解…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...