grid组件(表格)是非常常用的组件,尤其是后台系统。它的制定也是五花八门的。因此jQuery有大量的grid组件,每个都庞大无比,集成各种功能,复杂得像Excel。但即便是这样,我们的产品经理总是能提出一些需求,让你死去活来。因此有时我们不需要一个功能丰富的grid,而是一个扩展性极好的grid。
avalon2强大的组件机制就此而生。
我们分析一下grid的结构。通常就是一个表头,表头固定。表身,放数据。表尾,总是一个分页栏或是汇总栏。因此,我们的grid写成这样就行了,其他都使用slot传进来,其可制性极强。
avalon.component('ms-grid', {
template: heredoc(function () {
/*
<div class="grid">
<div><slot name="header"/></div>
<div><slot name="tbody"/></div>
<div class="pager"><slot name="pager" /></div>
</div>
*/
}),
defaults: { }
})
分页栏,我们使用之前的分析就好了。于是组件容器里写成这样:
<xmp :widget="{is:'ms-grid'}">
<table slot='header' class="header">
<tr>
<td :for="el in @header" style="width:200px" >
{{el}}
</td>
</tr>
</table>
<table slot="tbody" class="tbody">
<tr :for="obj in @data |limitBy(@count, @start)">
<td :for="el in obj | selectBy(@header)" style="width:200px">{{el}}</td>
</tr>
</table>
<ms-pager slot="pager" :widget="{onReady:@aaa}" />
</xmp>
对于这个grid本身而言,最难的部分就是使用limitBy与selectBy这两个过滤器。limitBy要与分析栏进行联动。selectBy要与表头联动。
然后我们加一点随机数据与样式吧。
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src='../../dist/avalon.js'></script>
<script>
function heredoc(fn) {
return fn.toString().replace(/^[^\/]+\/\*!?\s?/, '').
replace(/\*\/[^\/]+$/, '').trim().replace(/>\s*</g, '><')
}
avalon.component('ms-grid', {
template: heredoc(function () {
/*
<div class="grid">
<div><slot name="header"/></div>
<div><slot name="tbody"/></div>
<div class="pager"><slot name="pager" /></div>
</div>
*/
}),
defaults: { }
})
function genData(n) {
var list = []
for (var i = 0; i < n; i++) {
list.push({
aaa: new Date - i,
bbb: Math.random().toString(32).replace(/0\./, ""),
ccc: (Math.random() + "").replace(/0\./, ""),
ddd: i
})
}
return list
}
var vm = avalon.define({
$id: 'widget1',
header: ['aaa','bbb','ccc'],
start: 0,
count: 10,
data: genData(300),
aaa: function (e) {
e.vmodel.$watch('currentPage', function (a) {
vm.start = a - 1
console.log(vm.start)
})
},
ddd: 'bbb'
})
avalon.component("ms-pager", {
template: heredoc(function(){
/*
<div class="pagination">
<ul>
<li :for="el in @pages"
:class="[ el == @currentPage && 'active' ]">
<a href="javascript:void(0)" :click="@gotoPage(el, $event)">{{el}}</a>
</li>
</ul>
</div>
*/
}),
defaults: {
totalPage: 25,
currentPage: 1,
showPage: 7,
pages: [1, 2, 3, 4, 5, 6, 7],
gotoPage: function (page, e) {
this.currentPage = page;
this.pages = this.getPages();
},
getPages: function () {
var pages = [];
var s = this.showPage, l = this.currentPage, r = this.currentPage, c = this.totalPage;
pages.push(l);
while (true) {
if (pages.length >= s) {
break;
}
if (l > 1) {
pages.unshift(--l);
}
if (pages.length >= s) {
break;
}
if (r < c) {
pages.push(++r);
}
}
return pages;
}
}
});
</script>
</head>
<body>
<style>
.header {
border:1px solid #000;
width: 600px;
border-collapse: collapse;
}
.header td{
border:1px solid #000;
text-align: center;
font-weight: 700;
height:30px;
color: #607fa6;
font-weight: 700;
}
.tbody{
width: 600px;
margin-top: -1px;
border:1px solid #000;
border-collapse: collapse;
}
.tbody td{
border:1px solid #000;
height: 30px;
}
.pagination ul{
list-style: none;
margin: 0;
padding: 0;
}
.pagination li{
float: left;
}
.pagination li a{
text-decoration: none;
display: inline-block;
width:40px;
height: 30px;
line-height: 30px;
text-align: center;
background: #fafafa;
color:#000;
}
.pagination .active a{
background: #009a61;
color:#fff;
}
.pager{
width:600px;
background: #fafafa;
}
.pager > *{
float: right;
}
</style>
<div ms-controller='widget1' >
<xmp :widget="{is:'ms-grid'}">
<table slot='header' class="header">
<tr>
<td :for="el in @header" style="width:200px" >
{{el}}
</td>
</tr>
</table>
<table slot="tbody" class="tbody">
<tr :for="obj in @data |limitBy(@count, @start)">
<td :for="el in obj | selectBy(@header)" style="width:200px">{{el}}</td>
</tr>
</table>
<ms-pager slot="pager" :widget="{onReady:@aaa}" />
</xmp>
</div>
</body>
</html>
大家可以到这里下到它的源码
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。