MVC+jQuery数据绑定①:列表绑定(二)

&qu其实挂MVC只在上一节有说道,我还是只写Jquery数据绑定吧。

我不知道别人是否使用过我这种绑定方法,这是我想出来的。所以一个人的想法会不会被别人所接受那是别人的看法。我只是分享下自己的方法。
当然,个人能力有限,愚昧的地方还望指出。
首先 试想写这个方法或者说绑定一个列表时需要碰到哪些问题? 如何在这个方法里解决大多数列表的问题?
Ⅰ、如何分页?
Ⅱ、绑定的是Url请求还是Array?
Ⅲ、列表加载后需要做什么处理?
Ⅳ、其他的问题... 
我们把绑定Table的方法写成一个Jquery的插件。 用起来就舒服一些。  
$("#lstTable").bindTable(....);
Ⅰ、如何分页?
但凡列表,都会有分页的问题。在我们这种绑定方法里分页无非是重新绑定列表,只不过请求的数据是后台给的另外一页的数据。
那么,我们的分页只不过是把一些分页连接的点击事件变成绑定请求,类似 
$(".pagelist a").click(function(){
    $("#lstTable").bindTable({pageIndex:xx});
});
假如翻页我们写成一个 $("#xx").Paper(...) 翻页后会如何记忆第一次请求传递的参数?  目前是把参数记忆在table的自定义属性里,而才callback则放在一个全局变量里。
Ⅱ、绑定的是Url请求还是Array?
绑定的数据源不一定是ajax请求,可能是ViewData、Model或其他自己整理好的Array,其实Url也是去获取Data,那就视绑定为已有数据而已
已有的数据如何分页?这不和后台已分好页的数据冲突了吗? 确实有点冲突,这个.... 目前ajax数据的分页我们还是按后台来分页吧-_-
Ⅲ、列表加载后需要做什么处理?
我们动态append to tBody的html内容是死的,里面的<a>、<input>可能没有自己的事件,除非里面已经写好了 onclick 。。 这样我们改动起来就失去了Jquery的事件绑定的优势。
所以绑定数据后,我们需要处理所有列表共通的事件绑定,另外需要一个callback方法来处理特定的需求。
Ⅳ、其他的问题... 
点击thead里的连接对数据排序如何处理?  翻页后前一页的已选中的checkbox如何记忆?其他还会发现... 好的方法是慢慢成熟演变的。
以上的问题都是我在实际开发中不断碰到的总结。
Jquery的插件的写法,随便找个插件我们就可以模仿的写下来。 类似$("##").FunctionName(..) 就是下面这种写法。
; (function($) {
   $.fn.FunctionName = function(...){};
})(jQuery);
如果手打代码太累了-。-而且不能高亮,但是代码会比较干净。可是我还是选择了粘贴现在在用的代码(还没做到理想状态),如果把代码打成一个演变的过程可能更容易理解
下面我们开始写bindTable这个扩展方法。
ContractedBlock.gif ExpandedBlockStart.gif 代码
 
     
; ( function ($) {
var callbackList = []; // 存放callback
var dataList = []; // 存放table的Data 非ajax请求分页
$.fn.bindTable = function (args) {
var me = this ;
if (me.length == 0 ) {
return me;
}
var id = me.attr( " id " ) || me.attr( " name " ) || me.attr( " class " );

// 定义需要的参数
var url, pageSize, pageIndex, recordCount, data, callback, listName, isappend, ispage, sort, desc;

var isFirst, isAjax;
// 检查传递的参数
switch (arguments.length) {
case 0 : //
args = {};
isFirst
= false ;
break ;
case 1 :
switch ( typeof (args)) {
case " string " : // 只传url
url = args;
isFirst
= true ;
isAjax
= true ;
args
= {};
break ;
case " number " : // 只传pageSize
pageIndex = args;
isFirst
= false ;
args
= {};
break ;
case " function " : // 只传callback
callback = args;
isFirst
= true ;
args
= {};
break ;
default :
data
= args.data;
if (data != undefined) {
isAjax
= false ;
}
break ;
}
break ;
case 2 : // 传2个参数
isFirst = true ;
isAjax
= true ;

if ( typeof (arguments[ 0 ]) == " string " ) { // url
url = arguments[ 0 ];
args.url
= url;
}
else if ( typeof (arguments[ 0 ]) == " object " ) { // data
data = arguments[ 0 ];
args.data
= data;
}

if ( typeof (arguments[ 1 ]) == " function " ) { // callback
callback = arguments[ 1 ];
}
args
= {};
args.callback
= callback;
break ;
}

// Ajax请求
url = url || args.url || me.attr( " datasource " );

if (url == undefined && data == undefined)
return me;

if (isFirst)
callbackList[id]
= undefined;
else
callback
= callbackList[id];

if (isAjax)
dataList[id]
= undefined;
else
data
= args.data || dataList[id];



// 是否填充
isappend = args.isappend || false ;
// 排序
sort = me.attr( " sort " ) || "" ;
desc
= me.attr( " desc " ) || "" ;

// 数据源成员名
listName = args.list || " list " ;


// 是否分页
ispage = args.ispage || me.attr( " ispage " ) != " false " ;

if ( ! ispage) {
pageIndex
= 1 ;
pageSize
= 0 ;
recordCount
= 0 ;
}
else {
pageIndex
= me.attr( " pageIndex " ) || args.pageIndex || 1 ;
pageSize
= args.pageSize || parseInt(me.attr( " pageSize " )) || Math.round(Math.round((window.screen.height - 500 ) / 26 ) / 5 ) * 5 ; // 分页

}


// 非填充 清空列表
if ( ! isappend) clearTbody(me);

// 如果是url请求
if (data == undefined)
data
= getDataByAjax(getRequestUrl());
if (data == undefined)
return me;

// 声明一个新的数据源 不污染原始结构
var dataSource = getDataSource(data, listName);

recordCount
= data.recordCount || data.RecordCount || dataSource.length;
$(me).attr(
" recordCount " , recordCount);


var currentPageData = getPageData(dataSource, pageIndex, pageSize, recordCount);

getTbody(me, currentPageData, isappend);

runCallback(callback, dataSource);

me.attr(
" dataSource " , url);

if (ispage) {
me.attr(
" pageIndex " , pageIndex);
me.attr(
" pageSize " , pageSize);
me.attr(
" recordCount " , recordCount);
me.attr(
" ispage " , ispage);
}

// 翻页
if (ispage) {
me.tablePage();
}
me.setLink();
return me;

// private function .....................................................................................................
function getRequestUrl() {
if (url.indexOf( " ? " ) == - 1 )
url
+= " ? " ;
else
url
= url.replace( / &?(pageIndex|pageSize|sort|desc|_)=([^&]*) / gi, "" );

url
+= " &sort= " + sort + " &desc= " + desc;
if (ispage)
url
+= " &pageIndex= " + pageIndex + " &pageSize= " + pageSize;

return url;
}
// .....................................................................................................
function getDataByAjax(url) {
var data;
$.ajax({
type:
" POST " ,
url: url,
async:
false , // 这里用了同步请求,IE6下会卡一下,如果用异步,则需要把后面的代码做成一个单独的方法。
success: function (d) {
if (d == "" )
data
= undefined;
else
data
= eval( " ( " + d + " ) " );
}
});
return data;
}
// .....................................................................................................
function clearTbody(table) {
$(
" .pagelist " , table).empty().hide();
$(
" tbody:eq(0) " , table).empty();
}
// .....................................................................................................
function getDataSource(data, listName) {
var dataSource = [];
if (data[listName] === undefined) {
dataSource
= data;
}
else if (data[listName] != null ) {
dataSource
= data[listName];
}
return dataSource;
}
// .....................................................................................................
function runCallback(callback, data) {
try {
$(
" >thead th input[type='checkbox'] " , me).attr( " checked " , "" );
}
catch (e) { }

if (callback != undefined) {
if ( typeof (callback) == " function " ) {
callback(data);
}
else {
try {
eval(callback)();
}
catch (e) { }
}
}

}
// .....................................................................................................
function getPageData(data, pageIndex, pageSize, recordCount) {
if (pageSize == 0 )
return data;

if (data.length <= pageSize)
return data;
var pageData = [];
var loop = pageSize * pageIndex;
if (loop >= recordCount) loop = recordCount;

for ( var i = (pageIndex - 1 ) * pageSize; i < loop; i ++ ) {
pageData.push(dataSource[i]);
}
return pageData;
};
// .....................................................................................................
function getTbody(table, data, isAppend) {

// 替换模板创建到列表
if ($( " >tbody " , table).length == 0 )
table.append(
" <tbody></tbody> " );

// 没有数据的显示
if (isAppend == false ) {
if (currentPageData.length == 0 ) {
$(
" >tbody " , table).html( " <tr><td colspan=' " + $( " thead th " , table).length + " '>暂时没有数据</td></tr> " );
$(
" >tfoot " , table).empty().hide();
return table;
}
}
$(
" tr:contains('暂时没有数据') " , table).remove();
$(
" >tbody " , table).append(replaceTemplate(table.getTemplate(), currentPageData)); // 这里执行数据替换
}
};


$.fn.selectAll
= function () {
var me = this ;
$(
" input[name='selectall'] " , me).click( function () {
$(
" tbody input[type='checkbox'] " , me).attr( " checked " , this .checked);
});
return me;
};

$.fn.getSelectedVal
= function () {
var idList = [];
$(
" tbody input[type='checkbox']:checked " , this ).each( function () {
idList.push(
this .value);
});
return idList;
}

})(jQuery);

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
     
; ( function ($) {
$.fn.tablePage
= function (recordCount, pageSize, pageIndex, alwaysShow) {

var me = this ;

recordCount
= parseInt(recordCount || me.attr( " recordCount " ) || 0 );
pageSize
= parseInt(pageSize || me.attr( " pageSize " ) || 10 );
pageIndex
= parseInt(pageIndex || me.attr( " pageIndex " ) || 1 );

alwaysShow
= !! alwaysShow;

var pageCount = parseInt(recordCount / pageSize);

if (recordCount % pageSize > 0 )
pageCount
++ ;
if (pageIndex > pageCount)
pageIndex
= pageCount;


if (pageCount == 1 && alwaysShow == false )
return me;

if (recordCount == 0 )
return me;


if ($( " >tfoot td " , me).length == 0 )
me.append(
" <tfoot><tr><td colspan='20'></td></tr></tfoot> " );

$(
" >tfoot td " , me).html(getPageHtml());
me.attr(
" recordCount " , recordCount);
me.attr(
" pageSize " , pageSize);
me.attr(
" pageIndex " , pageIndex);
this .setPageLink(); // 设置分页的链接
return me;

function getPageHtml() {

var getLink = function (pageIndex, linkText) {
linkText
== linkText || pageIndex;
return " <span><a href=\ " # " + pageIndex + " \ " > " + linkText + " </a></span> " ;
}

var getSpan = function (text) {
return " <span> " + text + " </span> " ;
}

var html = " <div class=\ " pagelist\ " > " ;
var first = " 首页 " ;
var prev = " 上一页 " ;
var next = " 下一页 " ;
var last = " 末页 " ;


if (pageIndex == 1 ) {
html
+= getSpan(first) + getSpan(prev);
}
else {
html
+= getLink( 1 , first) + getLink(pageIndex - 1 , prev);
}

var listSize = 5 ;

var listIndex = parseInt(pageIndex / listSize);

if (pageIndex % listSize == 0 ) listIndex -= 1 ;

if (listIndex > 0 )
html
+= getLink((listIndex - 1 ) * pageSize + 1 , " ... " );

var beginPage = listIndex * listSize + 1 ;

var loopTimes = beginPage + listSize;

for (; beginPage <= loopTimes && beginPage <= pageCount; beginPage ++ ) {
if (beginPage == pageIndex)
html
+= " <span class=\ " current\ " > " + pageIndex + " </span> " ;
else
html
+= getLink(beginPage, beginPage);
}
if ((listIndex + 1 ) * pageSize < pageCount)
html
+= getLink((listIndex + 1 ) * pageSize + 1 , " ... " );

if (pageIndex == pageCount) {
html
+= getSpan(next) + getSpan(last);
}
else {
html
+= getLink(pageIndex + 1 , next) + getLink(pageCount, last);
}
return html += " </div> " ;
}

};

$.fn.setPageLink
= function () {
var me = this ;
$(
" tfoot .pagelist a " , this ).unbind( " click " ).click( function () {
var thisPageIndex = $( this ).attr( " href " );
thisPageIndex
= thisPageIndex.substring(thisPageIndex.lastIndexOf( " # " ) + 1 );
me.attr(
" pageindex " , thisPageIndex);
me.bindTable();
});
return me;
};

})(jQuery);

 

转载于:https://www.cnblogs.com/mad/archive/2009/09/11/1564790.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值