项目的需求也为减轻服务器的负担,需要使用到前端分页器,当页面加载的时候就显示数据。于是就去下载了一个分页器,但是试了几次都是失败,不知道错哪儿了,望大家提供帮助,谢谢!
window.onload = function () {
$.get('/web_admin/member_info/', function (res) {
if (res.code === 200) {
members = JSON.parse(res.members);
fenye(members, 16)
/*var table = $("table tbody ");
table.html('')
table_tr_str = ""
for (var j in members) {
table_tr_str += "<tr><td>" + members[j]['id'] + "</td><td>" + members[j]['user_phone'] + "</td><td>" + members[j]['user_register_date'] + "</td></tr>"
}
table.append(table_tr_str)*/
}
});
function fenye(datas, pages) {
console.log(datas)
var options = {
"id": "page",//显示页码的元素
"data": datas,//显示数据
"maxshowpageitem": 3,//最多显示的页码个数
"pagelistcount": pages,//每页显示数据个数
"callBack": function (datas) {
table=$("table tbody")
table.html('')
table_tr_str = ""
for (var j in datas) {
table_tr_str += "<tr><td>" + datas[j]["id"] + "</td><td>" + datas[j]["user_phone"] + "</td><td>" + datas[j]["user_register_date"] + "</td></tr>"
}
table.append(table_tr_str)
}
};
page.init(datas.length, 1, options);
}
}
现在的问题是page它不是function,截图如下:
page.init(datas.length, 1, options)
init,, 你的page对象是什么?打印一下,也许是undefined
window.onload = function () {
$.get('/web_admin/member_info/', function (res) {
if (res.code === 200) {
members = JSON.parse(res.members);
fenye(members, 16)
}
});
function fenye(datas, pages) {
var options = {
"id": "page", //显示页码的元素
"data": datas, //显示数据
"maxshowpageitem": 3, //最多显示的页码个数
"pagelistcount": pages, //每页显示数据个数
"callBack": function (datas) {
table = $("#table tbody")
table.html('')
table_tr_str = ""
for (var j in datas) {
table_tr_str += "<tr><td>" + datas[j]["id"] + "</td><td>" + datas[j]["user_phone"] + "</td><td>" + datas[j]["user_register_date"] + "</td></tr>"
}
table.append(table_tr_str)
}
};
page.init(datas.length, 1, options);
}
}
对于存在嵌套结构的对象,我们就应该引入递归和类型判断系统了。
国际惯例三步走:
===
比对,如果false
则直接return
判断数据类型由于方法很多,也不是本篇的重点,所以不展开来讲,只放一个我喜欢用的方法,大家可以随意取用。
// 判断数据类型
function getDataType(data) {
const temp = Object.prototype.toString.call(data);
const type = temp.match(/\b\w+\b/g);
return (type.length < 2) ? 'Undefined' : type[1];
}
有了类型判断方法后,我们就可以开始写新方法啦!
function isObjectChanged(source, comparison) {
let isChanged = false
for (let key in source) {
// 由于Object和Array都属于我们要特殊判断的数据类型,所以要提前做一下判断
if (getDataType(source[key]) === 'Object' || getDataType(source[key]) === 'Array') {
// 由于isChanged默认值就是false,所以我们只在isObjectChanged返回true的时候改变状态
if (isObjectChanged(source[key], comparison[key])) {
isChanged = true
}
} else if (source[key] !== comparison[key]) {
isChanged = true
}
}
return isChanged
}
测试一下
const tar1 = {
name: '张三',
age: 12,
address: '上海市浦东新区',
array: [1, 2, 3],
children: {
age: 12,
name: '李四',
address: '上海市黄浦区',
}
}
const tar2 = {
name: '张三',
age: 12,
address: '上海市浦东新区',
array: [1, 2, 3, 4],
children: {
name: '李四',
age: 12,
address: '上海市黄浦区',
}
}
const tar3 = {
age: 12,
name: '张三',
address: '上海市浦东新区',
array: [1, 2, 3],
children: {
age: 13,
name: '李四',
address: '上海市黄浦区',
}
}
const tar4 = {
age: 12,
name: '张三',
address: '上海市浦东新区',
array: [2, 3, 1],
children: {
name: '李四',
age: 12,
address: '上海市黄浦区',
}
}
isObjectChanged(tar1, tar2) //false
isObjectChanged(tar1, tar3) //true
isObjectChanged(tar1, tar4) //true
目前看起来一切都如我们所愿,即使带上Array我们都不怕。
真的没问题了吗?我们加大难度再来测试一下。
const tar1 = {
name: '张三',
age: 12,
address: '上海市浦东新区',
array: [1, 2, 3],
children: {
age: 12,
name: '李四',
address: '上海市黄浦区',
}
}
const tar2 = {
name: '张三',
age: 12,
address: '上海市浦东新区',
array: [1, 2, 3, 4],
children: {
age: 12,
name: '李四',
address: '上海市黄浦区',
array: [1, 2, 3, 4],
}
}
isObjectChanged(tar1, tar2) // false
什么情况?这么明显的区别却在我们的方法里直接被忽视了?这是为啥呢?
原来我们在判断的时候,只根据源数据的属性来进行判断,如果是对比数据包含了源数据,且对比数据与源数据重合的部分都没有发生改变,那我们的方法就好像被别人遮住了一部分视野,再怎么对比都对比不出来啦。
仔细审视一下我们的代码,其中还有一个缺陷: 我们这个方法的目的就是为了判断是否存在变化,假如存在变化就可以立即返回结果,而不需要再傻傻的把循环跑完。
那么我们就继续优化吧!
function isObjectChanged(source, comparison) {
// 由于'Object','Array'都属于可遍历的数据类型,所以我们提前定义好判断方法,方便调用
const iterable = (data) => ['Object', 'Array'].includes(getDataType(data));
// 如果源数据不是可遍历数据,直接抛错,主要用于判断首次传入的值是否符合判断判断标准。
if (!iterable(source)) {
throw new Error(`source should be a Object or Array , but got ${getDataType(source)}`);
}
// 如果数据类型不一致,说明数据已经发生变化,可以直接return结果
if (getDataType(source) !== getDataType(comparison)) {
return true;
}
// 提取源数据的所有属性名
const sourceKeys = Object.keys(source);
// 将对比数据合并到源数据,并提取所有属性名。
// 在这里进行对象合并,首先是要保证 对比数据>=源数据,好处一:后边遍历的遍历过程就不用做缺省判断了。
const comparisonKeys = Object.keys({...source, ...comparison});
// 好处二:如果属性数量不一致说明数据必然发生了变化,可以直接return结果
if (sourceKeys.length !== comparisonKeys.length) {
return true;
}
// 这里遍历使用some,some的特性一旦找到符合条件的值,则会立即return,不会进行无意义的遍历。完美符合我们当前的需求
return comparisonKeys.some(key => {
// 如果源数据属于可遍历数据类型,则递归调用
if (iterable(source[key])) {
return isObjectChanged(source[key], comparison[key]);
} else {
return source[key] !== comparison[key];
}
});
}
嗯~~ 一看代码量就知道很稳,直接上大招测试!
const tar1 = {
name: '张三',
age: 12,
address: '上海市浦东新区',
array: [1, 2, 3],
children: {
age: 12,
name: '李四',
address: '上海市黄浦区',
}
}
const tar2 = {
name: '张三',
age: 12,
array: [1, 2, 3],
address: '上海市浦东新区',
children: {
age: 12,
address: '上海市黄浦区',
name: '李四',
}
}
const tar3 = {
name: '张三',
age: 12,
array: [1, 3, 2],
address: '上海市浦东新区',
children: {
age: 12,
address: '上海市黄浦区',
name: '李四',
}
}
const tar4 = {
name: '张三',
sex: '女',
address: '上海市浦东新区',
array: [1, 2, 3, 4],
children: {
age: 12,
name: '李四',
address: '上海市黄浦区',
array: [1, 2, 3, 4],
}
}
const tar5 = {
name: '张三',
age: 12,
address: '上海市浦东新区',
array: [1, 2, 3, 4],
children: {
age: 12,
name: '李四',
address: '上海市黄浦区',
array: [1, 2, 3, 4],
}
}
isObjectChanged(tar1, tar2) //false
isObjectChanged(tar1, tar3) //true
isObjectChanged(tar1, tar4) //true
isObjectChanged(tar1, tar5) //true
完美~ 所有变化都被我们的方法给判断出来了!