初次接触avalon,很多地方理解起来还是有点慢。还是动手写个demo跑一跑学得更快。
平时的工作中经常用到各种列表,因此第一次写demo也是选择写一个常用到的无刷新分页列表。翻了半天教程和资料,居然找不到一个现成的例子。根据avalon作者司徒大大的说法,他并不推荐用grid的形式来实现,而是推荐使用mmState。跟avalon配套的oniui里有“smartgrid”、“simplegrid”两种列表控件,但是也没有一个完整的分页跳转例子。我相信还是有很多人对grid有需求的。在参考了smartgrid、pager控件的接口用法及范例,最后鼓捣出一个可用的异步加载无刷新分页demo出来。
avalon1.5以上已经不兼容oniui了,因此我用的还是avalon1.4.
具体代码如下:
一、html页面
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<script type="text/javascript" src="../../Scripts/jquery-easyui-1.4.4/jquery.min.js"></script>
<script type="text/javascript" src="../../Scripts/JMBM/Common/common.js"></script>
<script type="text/javascript" src="../../Scripts/JMBM/Common/Accredit.js"></script>
<script type="text/javascript" src="../../Scripts/avalon.oniui-master/avalon.js"></script>
<script type="text/javascript" src="../../Scripts/JMBM/AvalonExamples/TestGrid.js"></script>
</head>
<body ms-controller="test">
<form id="form1" runat="server">
<div ms-widget="smartgrid,sg1"></div>
<button ms-click="reRenderData">重新渲染数据</button>
<button ms-click="clearData">清空数据</button>
</form>
</body>
</html>
<input type="hidden" id="hidUser"/>
<input type="hidden" id="hidAuthenticationType"/>
<input type="hidden" id="hidLocation"/>
<input type="hidden" id="hidToken"/>
<input type="hidden" id="tid" runat="server" />
<input type="hidden" id="sid" runat="server" />
<script language="javascript" type="text/javascript">
$("#hidUser").val("<%=HttpContext.Current.User.Identity.Name.Replace("\\","\\\\")%>");
$("#hidAuthenticationType").val("<%=HttpContext.Current.User.Identity.AuthenticationType%>");
</script>
html文件中引用了jquery和avalon,jquery主要是用它的ajax。其中需要注意的是jquery.js和avalon.js的引用顺序,avalon要在jquery之后,不然有可能出现脚本错误。
二、js脚本习惯性地独立出来,成为单独的js文件
require(["smartgrid/avalon.smartgrid"], function () {
var getDatas= function(page,rows,sg) {
var url = "../../AjaxItemService/GetManageArticleList.cspx?t=" + getRandom(100);
$.ajax({
url: url, type: "post",
data:
{
ArticleState: 1,
Name: $("#hidUser").val(),
ListType: "Admin",
page:page,
rows: rows,
AuthenticationType: $("#hidAuthenticationType").val()
},
success:function (json) {
if (json != "0") {
sg.data = json.rows;
sg.pager.totalItems=json.total;
sg.render()
}
}
});
}
avalon.define("test", function (vm) {
vm.$skipArray = ["smartgrid"]
vm.reRenderData = function () {
var grid = avalon.vmodels.sg1;
getDatas(grid.pager.currentPage, grid.pager.perPages, grid);
}
vm.clearData = function () {
var sg1 = avalon.vmodels.sg1
sg1.data = []
sg1.render()
}
vm.smartgrid = {
autoResize: false,
$skipArray:["dropdown","pager"],
columns: [
{
key: "ArticleTitle", //列标识
name: "文章名称", //列名
sortable: true, //是否可排序
isLock: true, //是否锁死列让其始终显示
align: "left", //列的对象方式
customClass: "ddd", //自定义此列单元格类
toggle: false, //控制列的显示隐藏
width: 400 //设置列的宽度
}, {
key: "ColumnName",
name: "栏目",
sortable: true,
width: 300
}, {
key: "Creator",
name: "作者",
//type: "Number",
sortable: true,
align: "right",
width: 300
}
],
pager: {
perPages: 10,
showPages:10,
options: [10, 20, 30],
canChangePageSize: true,
onJump: function (e, pagerVM) {
getDatas(pagerVM.currentPage, pagerVM.perPages, avalon.vmodels.sg1);
},
dropdown: {
onChange: function (newValue, oldValue, vmodel)
{
var grid = avalon.vmodels.sg1;
grid.pager.perPages = newValue;
getDatas(grid.pager.currentPage, grid.pager.perPages, grid);
}
},
onInit: function (vmodel) {
getDatas(1, vmodel.perPages, avalon.vmodels.sg1);
}
},
onInit: function (vmodel) {
},
data:[]
}
})
avalon.scan()
})
代码比较简单,懂一些jquery和avalon的都应该看得懂。要点在以下几个地方:
一、基于ajax的延时性,grid数据的加载应在$.ajax的回调函数中。开始的时候想把跟官方的例子一样,将数据生成写在define的data属性中,像下面的写法:
avalon.define("test", function(vm) {
vm.$skipArray = ["smartgrid"]
vm.smartgrid = {
autoResize: false,
columns: [
{
key : "name", //列标识
name : "姓名", //列名
sortable : true, //是否可排序
isLock : true, //是否锁死列让其始终显示
align: "left", //列的对象方式
defaultValue: "shirly", //列的默认值
customClass: "ddd", //自定义此列单元格类
toggle: false, //控制列的显示隐藏
width: 400 //设置列的宽度
}, {
key : "age",
name : "年龄",
sortable : true,
width: 300
}, {
key : "salary",
name : "薪水",
type : "Number",
sortable : true,
align: "right",
width: 300
}
],
data: getDatas(100)
}
})
实际执行的时候是获取不到数据的。
二、关于数据初始化时机的选择
开始的时候是选择在smartgrid的onit过程中调用getDatas()函数,同时将smartgrid作为对象传到getDatas()函数里面,在getDatas()的回调函数中render simplegrid对象。后来在做分页的时候发现这个时候pager并未生成(也就是smartgrid与它的pager其实是两个对象,pager生成在后),所以将getDatas改写到pager的onit过程中了。
三、目前存在的不足
目前经过测试,整个写法基本能满足我平常的需求。性能暂时还没有测试。
跟之前用惯的easyui来比,初始化过程的代码量差不多。不过在更改页面显示条数的过程中,easyui的datagrid能记住当前的页码,更改后所在页码不变;而smartgrid会跳转回第一页。往后准备再看看smartgrid的源码,看有没有办法改进。