学习如何分页
在此次项目中我们的童‘总监’做成了分页的功能,在此我想总结一下。
采用了jqPaginator插件,源码如下:
js部分
axios.post('/allMovies').then(function (ans) {
let mynum = parseInt((ans.data.length/16))+1;
let str = '';
$('.ttx-my-number').jqPaginator({
totalPages: mynum,
visiblePages: 20,
currentPage: 1,
onPageChange: function (num, type) {
let str = '';
let mycurrentnum = (num-1)*16;
let myendnum = num*16 - 1;
if(myendnum > ans.data.length - 1){
myendnum = ans.data.length - 1;
}
for (let i = mycurrentnum; i <=myendnum; i++) {
str += '<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12 ttx-movie">';
str += `<a onclick="myonclickhrf(${ans.data[i].id})">![](${ans.data[i].movieimg})</a>`;
str += `<p class="ttx-movie-text"><a onclick="myonclickhrf(${ans.data[i].id})" >${ans.data[i].name}</a><strong>${ans.data[i].score}</strong></p>`;
str += `</div>`;
}
$(".ttx-movie-container").empty().append(str);
}
});
});
html部分
<div class="col-lg-9 col-md-9 col-sm-9 col-xs-9 ttx-right">
<ol class="breadcrumb ttx-bread">
<li class="active">全部影片</li>
</ol>
<div class="row ttx-movie-container">
</div>
<nav aria-label="...">
<ul class="pagination ttx-my-number">
</ul>
</nav>
</div>
解析
此次样式上利用了boostrap框架,js上利用的是jqPaginator插件。
axios.post('/allMovies').then(function (ans) {}
axios前端向后端('/allMovies')路由post数据,then()里的函数是数据接收后的回调函数,ans是接受的数据,类型是对象,ans的data属性的值是数组
let mynum = parseInt((ans.data.length/16))+1;
求出ans的data属性值的长度
$('.ttx-my-number').jqPaginator({})
利用jquery方法,此为给class为ttx-my-number调用一个js函数
totalPages: mynum,
visiblePages: 20,
currentPage: 1,
总页数为后台传来的数据mynum,分页的总页数为20,当前页码为1
onPageChange: function (num, type) {}
回调函数,当换页时触发(包括初始化第一页的时候),会传入两个参数:
1、“目标页"的页码,Number类型
2、触发类型,可能的值:“init”(初始化),“change”(点击分页)
let mycurrentnum = (num-1)*16;
*16代表每页有16个电影,mycurrentnum表示点击后目标页后所需要加载的第一个数据
myendnum = num*16 - 1;
myendnum代表点击目标页数所需要加载的最后一个数据(电影)
if(myendnum > ans.data.length - 1){
myendnum = ans.data.length - 1;
}
如果目标页所需要加载的最后一个数据大于后台提供的数据,则最后一个数据就是后台提供的最后一个数据。
for (let i = mycurrentnum; i <=myendnum; i++) {}
表示加载点击目标页第一个数据到最后一个数据
str += '<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12 ttx-movie">';
第一层div:加样式
<a onclick="myonclickhrf(${ans.data[i].id})">
![]($ {ans.data[i].movieimg})
</a>
第二层div: 添加图片,图片也是一个链接
<p class="ttx-movie-text">
<a onclick="myonclickhrf(${ans.data[i].id})" >${ans.data[i].name}</a>
<strong>${ans.data[i].score}</strong>
</p>
第三层div: 添加文字描述,文字也是链接
$(".ttx-movie-container").empty().append(str);
jquery方法:取class为ttx-movie-container,empty()将原本属于ttx-movie-container的子节点以及其文本内容清除(不包括本身),append()为ttx-movie-container添加刚刚动态创建的新节点和内容。
总结:
先向后台取回所有数据,点击目标页后,先清空页面上的已有数据后加载目标页所需要的第一个到最后一个数据,分页完毕。做到了页面部分刷新,且不用多次请求数据。
扩展:
可以延伸一些小功能,如:
按输入页数查询:
可以在
<nav aria-label="..."> </nav>
后添加一个input的搜索框,前端取得数据后将输入结果赋给mycurrentnum
让用户控制页数
也可添加一个input输入框,将*16的16作为传入参数cout(自定义),前端取得数据后将输入结果赋给cout
查询功能总结
本次项目查询功能我们小组实现了“分类查询”,“模糊查询”,“分类后模糊查询”,其中有一些需要学习的地方,以后可能会常用
源码如下:
前端JS部分
$(document).ready(function () {
$('.cr-mysubmit').on('click',function () {
let myselect = $('.cr-search-select').find("option:selected").html();
let myinput = $('.cr-myinput').val();
if(myinput){
if(myselect === '全部电影'){
$.post('/oneSearchResult',{moviename:myinput},function (ans) {
if(ans){
let str = '';
for (let i = 0; i < ans.length; i++) {
str += '<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12 ttx-movie">';
str += `<a onclick="myonclickhrf(${ans[i].id})">![](${ans[i].movieimg})</a>`;
str += `<p class="ttx-movie-text"><a onclick="myonclickhrf(${ans[i].id})" >${ans[i].name}</a><strong>${ans[i].score}</strong></p>`;
str += `</div>`;
}
$(".ttx-movie-container").empty().append(str);
}
});
}else {
$.post('/searchResult',{comment:myselect,moviename:myinput},function (ans) {
if(ans){
let str = '';
for (let i = 0; i < ans.length; i++) {
str += '<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12 ttx-movie">';
str += `<a onclick="myonclickhrf(${ans[i].id})">![](${ans[i].movieimg})</a>`;
str += `<p class="ttx-movie-text"><a onclick="myonclickhrf(${ans[i].id})" >${ans[i].name}</a><strong>${ans[i].score}</strong></p>`;
str += `</div>`;
}
$(".ttx-movie-container").empty().append(str);
}
});
}
}else {
return bootbox.alert("请填写电影名称!");
}
});
后端服务器部分
//获得一个电影的搜索结果
app.post("/oneSearchResult",urlencodedParser, function (req, res) {
let moviename=req.body.moviename;
req.models.T_movie.find({name:orm.like("%"+moviename+"%")}, function (err, movies) {
if (err) throw err;
res.send(movies);
});
});
/*得到这个电影名称的搜索结果 OK*/
app.post("/searchResult",urlencodedParser, function (req, res) {
let moviename=req.body.moviename;
let comment=req.body.comment;
req.models.T_movie.find({name:orm.like("%"+moviename+"%"),comment:orm.like("%"+comment+"%")}, function (err, movies) {
if (err) throw err;
res.send(movies);
});
});
html部分
<div class="navbar-form navbar-right">
<div class="form-group">
<select class="form-control cr-search-select " id="comment">
<option role="presentation"><a href="#">全部电影</a></option>
</select>
<input type="text" class="form-control cr-myinput" placeholder="搜索电影">
</div>
<button class="btn btn-default cr-mysubmit" >
<span class="glyphicon glyphicon-search">
</span>
</button>
</div>
- 获取下拉列表已经选中的值
let myselect = $('.cr-search-select').find("option:selected").html();
- 获取输入框值
let myinput = $('.cr-myinput').val();
- 清空原有元素,加载动态创建元素
$(".ttx-movie-container").empty().append(str);
- 搜索一条数据,模糊搜索
req.models.T_movie.find({name:orm.like("%"+moviename+"%")}, function (err, movies) {
if (err) throw err;
res.send(movies);
});
- 种类加模糊搜索
数据发送: {comment:myselect,moviename:myinput}
后台接收: req.models.T_movie.find({name:orm.like("%"+moviename+"%"),comment:orm.like("%"+comment+"%")}, function (err, movies) {
if (err) throw err;
res.send(movies);
});
});
跨页面传输
本次小组采用的是利用url参数跨页面传输数据,核心代码如下:
点击电影图片触发函数,给url添加参数
function myonclickhrf(myid) {
let myname = $('.ysj-login-name').html();
if(myname){
window.location.href = "/moviecontain.html?id="+myid+"&name="+myname
}else {
window.location.href = "/moviecontain.html?id="+myid+"&name="
}
}
其中参数myid可以是后台传来的用户ID,也可以是从html中获取的用户ID,视情况而定。
将url参数取出,如果参数存在则利用参数显示用户名,如果不存在则显示固定内容
let myurl = window.location.href.split("?id=");
myurl = [myurl[1].split('&name=')[1], myurl[1].split('&name=')[0]];
if (myurl[0]) {
$('.ysjLogin').html("你好" + myurl[0]);
} else {
bootbox.alert("您未登录,请去主页进行登录注册!");
$('.ysjLogin').html("你好,游客!");
}
从而实现通过url参数判断用户登陆状态
知识延伸
其他跨页面消息传输方法
- 用窗口对象的message事件监控
接收从其它窗口发来的消息
window.addEventListener('message',functio(){},false);
向其它窗口发送消息
otherwindow.postMessage(message,targetOrigin);
参数message为所发送的消息,可以为静态内容也可以为javascript对象
参数targetOrigin为接收消息的对象窗口的url地址
otherWindow为要发送窗口对象的引用,可以通过window.open返回该对象,或通过对window.frames数组制定序号或名字的方式来返回单个frame所属的窗口对象.
关于使用git来进行团队协作
思路上:
我们应该在本地仓库上有master和another(自定义)分支,在远程仓库上也有master和another分支(名字和本地仓库一样相对应),为什么我们需要两个分支呢,因为如果你在本地的master上工作,当你想提交到远程仓库之前如果有队友已经提交过新代码了,你本地master上(除了你加的)代码就和远程仓库的代码不同,git则会报你无法push并提示你要pull,但是你执行git pull 又会提示你本地仓库的代码已经超过远程仓库的代码的进程,不是队友提交之前远程master上的代码,就会出现矛盾无法pull(后面讲解决办法),所以我们需要先在本地的another上作业,并保持本地的master代码是最新的远程master代码(经常git pull origin master),当做好改动后将本地的another提交到远程的another上,再将远程的another和远程的master融合,再用git pull origin master将远程的master拉到本地的master上就可以实现无障碍代码流通咯!
(总结:本地的master是远程的最新的版本之前的版本就不会有冲突了)
步骤上:
-
git checkout -b another (创建本地another分支并进入another分支)
(git branch another 创建分支, git checkout another 进入分支 )
git add filePath(将修改内容添加到本地仓库another分支的缓存区上)
git commit -m'text'(将add的内容提交到本地仓库的another分支上)
git checkout master(从another分支退出进入本地master分支)
git pull origin master(将远程master分支内容拉到本地master分支)
git checkout another(从本地master分支进入本地another分支)
git rebase master(将第5步拉下来的代码和本地master分支以复位基底的方式融合)
手动解决冲突
-
git push origin another(将本地的another分支推到远程的another分支上)
(完整写法:git push origin another:another 不用担心你远程分支还没创建,github会自动帮你创建)
点击 pull request(在远程仓库界面进入自己提交的分支,申请提交至远程master分支)
审核代码,代码通过,融合至master分支
回到第一步