项目实训——数据渲染数据引擎

项目实训——数据渲染数据引擎

  • 数据渲染
    • layui卡片布局
    • layui分页
    • layui数据引擎
  • 遇到的问题

今天的任务就是要做出每个版块的页面。板块页面最重要就是数据的渲染。为了样式的统一,我继续使用layui,在这里用的是模板引擎laytpl。

数据渲染

layui卡片布局

为了美观,我使用了卡片式布局。将数据引擎和卡片布局结合起来,可以同时实现对美观和实用的要求。

<div class="layui-card">
	<div class="layui-card-header">卡片面板</div>
  	<div class="layui-card-body">
       卡片式面板面板通常用于非白色背景色的主体内
        <br>
	从而映衬出边框投影
	</div>
</div>

layui分页

layPage 致力于提供极致的分页逻辑,既可轻松胜任异步分页,也可作为页面刷新式分页。

<script>
	layui.use('laypage', function(){
		var laypage = layui.laypage;
		//执行一个laypage实例  
		laypage.render({
			elem: 'test1' //注意,这里的 test1 是 ID,不用加 # 号
			,count: 50 //数据总数,从服务端得到  
		});
	});
</script>

layui数据引擎

laytpl 是 JavScript 模板引擎,在字符解析上有着比较出色的表现,欠缺之处在于异常调试上。与一般的字符拼接不同的是,laytpl 的模板可与数据分离,集中把逻辑处理放在 View 层,提升代码可维护性,尤其是针对大量模板渲染的情况。
第一步,编写模版。我们可以使用一个script标签存放模板。以showoffer.html为例:

<script id="imgCardScript" type="text/html">
    <ul>
        {{#  layui.each(d, function(index, item){
                var url = "jobdetails?jobid="+ item.job_ID;//这里是岗位的具体链接
        }}
        <li>
            <div class="layui-card showcard" style="margin-bottom: 20px;" >
                <div class="layui-card-header"  style="padding:5px 0 45px 20px;font-size: 22px;">
                    <div style="width: 80%;">
                        <!-- 点击进入岗位具体页面-->
                        <a title={{item.title}} style="color: #009688;" href={{url}}>{{item.title}}</a>
                    </div>
                    <span style="float: right;margin-right: 50px;font-size:18px;color:#4d2eb3;display: inline-block;margin-top: -40px ">{{item.company_name}}</span>
                </div>
                <div class="layui-card-body">
                    <p><span class="subtitle">截止日期:</span> {{item.ddl||'暂无'}}</p>
                    <p><span class="subtitle">城市:</span>{{item.cities||'暂无'}}</p>
                    <hr>
                    <p><span class="subtitle">关键词:</span>{{item.keywords}}</p>
                </div>
            </div>
        </li>
        {{#
        }); }}
        {{#  if(d.length === 0){ }}
        无数据
        {{#  } }}
    </ul>
</script>

第二步,建立视图。用于呈现渲染结果。

<div id="view" style="width: 60%;margin:60px 0 30px 10%;"></div>

第三步,获取后台传来的数据

<script type="text/javascript">
    function getdata(url) {
        var total;
        $.ajax({//用来得到数据总条数和第一页
            url: url,
            dataType: "json",
            data: {"cur": "1", "limit": "10"},
            success: function (json) {
                console.log(json.searched);
                if (json.code == 0) {
                    total = json.count;//总条数
                    console.log(total);
                    data = json.data;
                    //渲染模板
                    var getTpl = imgCardScript.innerHTML
                        , view = document.getElementById('view');
                    layui.use(['laytpl'], function (laytpl) {
                        laytpl(getTpl).render(data, function (html) {
                            view.innerHTML = html;
                        });
                    });
                    //进行分页
                    layui.use('laypage', function () {
                        var laypage = layui.laypage;
                        //执行一个laypage实例
                        laypage.render({
                            elem: 'laypage' //注意,这里的 test1 是 ID,不用加 # 号
                            , count: total //数据总数
                            ,limit:10
                            , layout: ['count', 'prev', 'page', 'next']
                            , jump: function (obj, first) { //obj包含了当前分页的所有参数,比如:
                                console.log(obj.curr); //得到当前页,以便向服务端请求对应页的数据。
                                page = obj.curr;  //改变当前页码
                                limit = obj.limit;//首次不执行
                                if (!first) {
                                    //加载余下页的数据
                                    $.ajax({//得到每一页的数据
                                        url: url,
                                        dataType: "json",
                                        data: {"cur": page, "limit": limit},
                                        success: function (json) {
                                            if (json.code == 0) {
                                                data = json.data;
                                                //后继数据渲染模板
                                                var getTpl = imgCardScript.innerHTML
                                                    , view = document.getElementById('view');
                                                layui.use(['laytpl'], function (laytpl) {
                                                    laytpl(getTpl).render(data, function (html) {
                                                        view.innerHTML = html;
                                                    });
                                                });
                                            }
                                        }
                                    });
                                }
                            }
                        });
                    });
                }
            }
        });
    }
    window.onload = getdata("/getoffers")
</script>

如你所见,相当复杂的一个function。首先通过ajax请求获取第一页的数据以及数据的总条数。数据总条数对于后面的分页实例的执行很重要。然后在执行分页实例的时候,通过ajax请求获取后继页的数据。
后台应该怎么传数据呢?以下是一个小小的范例:

@RequestMapping("/getoffers")
@ResponseBody
public  String getoffers(@RequestParam(value = "cur",defaultValue = "") String cur,@RequestParam(value = "limit",defaultValue = "") String lim,
                         @RequestParam(value = "search",defaultValue = "") String search,HttpServletRequest request){
    int page = Integer.parseInt(cur);//页数
    int limit = Integer.parseInt(lim);//一页限制条数
    JSONObject offerlist = null;
    List<Job> joblist = new ArrayList<Job>();
    for(int i = 0;i<15;i++) {
        Job job = new Job();
        job.setJob_ID((long)11);
        job.setTitle("数据分析员一一一一————————!");
        job.setCompany_name("随便");
        job.setCities("济南");
        job.setKeywords("python");
        job.setDdl(new Date());
        Job job1 = new Job();
        job1.setJob_ID((long)112);
        job1.setTitle("数据分析员");
        job1.setCompany_name("随便");
        job1.setCities("深圳");
        job1.setKeywords("python,数据挖掘");
        job1.setDdl(new Date());
        joblist.add(job);
        joblist.add(job1);
    }
    int size = joblist.size();//总条数
    if (page * limit <= size) {//检查是否为最后一页
        joblist = joblist.subList((page - 1) * limit, page * limit);
    } else {
        joblist = joblist.subList((page - 1) * limit, size);
    }
    offerlist = new JSONObject();
    if("".equals(search))//判断是否有进行搜索
        offerlist.put("searched",0);
    offerlist.put("searched",search);
    offerlist.put("code", 0);
    offerlist.put("data",joblist);
    offerlist.put("count", size);
    return offerlist.toString();
}

实现效果如下:
在这里插入图片描述

遇到的问题

因为还要实现推荐功能,同样也要使用模板引擎呈现数据。这样一个网页就要使用两个模板引擎。但这样就出现问题了:数据会在两个模板里反复横跳,根本没有办法保证下一次刷新就出现什么。这一下我就懵了,搜遍全网都找不到解决方案。后来我突然间灵光一闪,如果令推荐功能里的数据渲染和岗位的数据渲染错开时间,那能不能成功避免呢?

//获得推荐岗位
function getrecommend() {
    $.ajax({//用来得到推荐的岗位,链接里user应该是userid
        url: "/getrecommend?user=" + [[${session.loginUser}]],
        dataType: "json",
        success: function (json) {
            if (json.code == 0) {
                data = json.data;
                //模板渲染
                var Tpl1 = likeScript.innerHTML
                    , recommend = document.getElementById('recommend');
                layui.use(['laytpl'], function (laytpl) {
                    laytpl(Tpl1).render(data, function (html) {
                        recommend.innerHTML = html;
                    });
                });
            }
        }
    });
}
window.onload = function () {
    //要比左侧岗位延迟一点才能保证不会渲染错地方
    setTimeout(getrecommend,20);
}

setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。为了减少延迟的时间,我进行了一些测试,只有不低于20毫秒才能保证不会渲染错,同时最小化页面加载的时间。

热门文章

暂无图片
编程学习 ·

PAT 1161 Merging Linked Lists

原题链接:暂无 关键词:链表 Given two singly linked lists L 1 =a 1 →a 2 →…→a n−1 →a n L1=a1→a2→…→an−1→an and L 2 =b 1 →b 2 →…→b m−1 →b m L2=b1→b2→…→bm−1→bm . If n≥2m n≥2m , you are supposed to reverse and merge the shorter one i…
暂无图片
编程学习 ·

java后端重点

java基础,设计模式,jvm原理,spring+springmvc原理及源码,linux,mysql事务隔离与锁机制,mongodb,http/tcp,多线程,分布式架构(dubbo,dubbox,spring cloud),弹性计算架构,微服务架构(springboot+zookeeper+docker+jenkins),java性能优化,以及相关的项目管理等…
暂无图片
编程学习 ·

BIO、NIO、AIO基本概念

BIO 采用BIO通信模型的服务端,通常由一个独立的Acceptor线程负责监听客户端的连接,它接收到客户端连接请求之后为每个客户端创建一个新的线程进行链路处理,处理完成后,通过输出流返回应答给客户端,线程销毁。 BIO主要的问题在于每当有一个新的客户端请求接入时,服务端必须…
暂无图片
编程学习 ·

致敬建党99年 | 不忘初心,砥砺前行

致敬建党99年 | 不忘初心,砥砺前行 七一建党节(1921-2020) 听风雨飘摇,看沧桑巨变 一个民族的图存、崛起、强盛 离不开一代代中华儿女的奋斗与牺牲 在此 热烈庆祝中国共产党成立99年共产党一路走来,始终坚持了为中国人民谋幸福、为中华民族谋复兴的初心和使命。 这一份不忘…
暂无图片
编程学习 ·

电商新手做亚马逊要怎样开始?

"说到互联网创业,很多人的第一个想到的是淘宝,但是很多人并不清楚,经过十几年的发展淘宝已经很难再进入了,利润也是下降到了最低,很多的卖家都在寻找机会做转型,而你一个毫无经验的小白现在进入,基本可以说很难生存,近年来,我国的跨境电子商务进入迅猛的发展阶段,…
暂无图片
编程学习 ·

机器视觉打光技巧

光源专家的8个打光技巧 机器视觉系统中的照明系统是极其重要的一部分,它的好坏直接影响着后面的图像处理。在听了一位日本光源专家的讲座之前,我其实对照明并不太了解,不就是将图像照亮以至于相机能够拍到图像吗?但事实并非如此,照明远非增强图像亮度这样简单,好的照明系…
暂无图片
编程学习 ·

纸片人算什么?教你造真“3D小姐姐”!可以动的模型

要说现在什么行业最赚钱,非游戏莫属!要说游戏中什么类型最赚钱?非3D建模莫属! 据统计,刚入行的从业人员均薪1万-1.3万,如果做到总监,行业平均年薪30万+!他们的日常就是创造游戏里各种各样的小姐姐和自己心仪的角色。 玩游戏的人都知道,第一眼吸引我们的总是游戏中精美…
暂无图片
编程学习 ·

sso单点登录

无状态登录 微服务集群中的每个服务,对外提供的都是Rest风格的接口。而Rest风格的一个最重要的规范就是:服务的无状态性,即:服务端不保存任何客户端请求者信息 客户端的每次请求必须具备自描述信息,通过这些信息识别客户端身份带来的好处是什么呢?客户端请求不依赖服务端…
暂无图片
编程学习 ·

那些不常见,但却非常实用的 css 属性

作者:寒水寺一禅https://segmentfault.com/a/11900000228515431、-webkit-line-clamp可以把 块容器 中的内容限制为指定的行数。并且在超过行数后,在最后一行显示"..."这是正常的展示display: -webkit-box; /*值必须为-webkit-box或者-webkit-inline-box*/ -webkit…
暂无图片
编程学习 ·

k8s(1)

k8s-集群搭建的三种方式,目前主流的搭建k8s集群的方式有kubeadm、minikube,二进制包。kubeadm 是一个工具,用于快速搭建kubernetes集群,目前应该是比较方便和推荐的,简单易用 kubeadm是Kubernetes 1.4开始新增的特性 kubeadm init 以及 kubeadm join 这两个命令可以快速创…
暂无图片
编程学习 ·

vue+ts报错 Parsing error: Unexpected token

1.检查是否安装 babel-eslint2.打开.eslint.js文件检查部分属性和下方的是否匹配// ESlint 检查配置 module.exports = {root: true,parserOptions: {parser: babel-eslint,sourceType: module},parser: "vue-eslint-parser",//------------env: {browser: true,node…
暂无图片
编程学习 ·

前端学习-javascript-(1)预览

组成 DOM—Document Object Model 文档对象模型—操作返回到文档(界面) doucument对象 ———————————————— BOM—Browser Object Model 浏览器对象模型—操作浏览器本身 window对象 ———————————————— ECMAScript 解释器 ———————————…
暂无图片
编程学习 ·

数据库---常用数据库的驱动程序

Oracle数据库 驱动程序包名:ojdbc6.jar 驱动类的名字:oracle.jdbc.driver.OracleDriverJDBC URL:jdbc:oracle:thin: @dpip:port: databasename 说明:驱动程序包名有可能会变 JDBC URL中各个部分含义如下: dbip –为数据库服务器的IP地址,如果是本地可写:localhost或127.…
暂无图片
编程学习 ·

用C语言解一元二次方程式的根

#include<stdio.h> #include<math.h> //需要用到一个sqrt()函数,该函数功能用于开方;//该函数运算结果数据类型为double类型;如果涉及到运算请将数据类型定义成浮点型! int main () {float a,b,c,x1,x2;printf("请分别输出方程式的系数,中间以空格分隔\n&…
暂无图片
编程学习 ·

mxnet安装环境配置

一、安装Miniconda 官方网址:https://conda.io/en/latest/miniconda.html 本人选择python3.7版本Windows64位 安装完成后打开Anaconda Prompt创建虚拟环境conda create –n env python=3.7 这里的env为自定义环境名激活环境 conda activate env 退出环境: conda deactivate查…
暂无图片
编程学习 ·

创建第一个 Flink 项目(Java版)

一、运行环境介绍Flink执行环境主要分为本地环境和集群环境,本地环境主要为了方便用户编写和调试代码使用,而集群环境则被用于正式环境中,可以借助Hadoop Yarn、k8s 或 Mesos等不同的资源管理器部署自己的应用。环境依赖:【1】JDK环境:Flink核心模块均使用 Java开发,所以…
暂无图片
编程学习 ·

A1076 Forwards on Weibo (30) 图的遍历BFS

本题思路 考虑转发,且有层数(即转发最多通过几个非直接follows),所以考虑用BFS,因为BFS不涉及递归之类的,所以要用Node设置layer值。 #include<cstdio> #include<iostream> #include<vector> #include<queue> #include<cstring> using nam…
暂无图片
编程学习 ·

5D3无裁切5.4K电影24P RAW视频设置、拍摄、后期全流程

在写教程之前,首先感谢繁华,送我了我达芬奇加密狗,你也可以购买,使用起来和官方2600元的没任何区别(文章最后有购买链接)相当稳定不卡顿、不闪退、全插件无水印,由于之前的收费,非发给我红包,不要都不行。 言归正传。 凡是安装过此店(下面有购买链接)摩灯固件5D3中文…
暂无图片
编程学习 ·

移动端常见布局方案

文章目录一.基本概念:(1)移动端兼容性处理:主要处理webkit内核即可。(2)解决屏幕适配问题的方案:(3)物理像素比的问题:(4)移动端特殊样式的处理二.移动端布局方案:1.单独制作移动端页:(1)流式布局(百分比布局)(2)弹性布局:(3)less+rem+媒体查询布局(4)混…