欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

AngularJS中的Directive自定义一个表格

程序员文章站 2022-06-06 20:37:48
先给大家说下表格的需求: ● 表格结构
name<...

先给大家说下表格的需求:

● 表格结构

<table>
<thead>
<tr>
<th>name</th>
<th>street</th>
<th>age</th>
</tr>
</thead>
<tbody>
<tr>
<td>></td>
<td>></td>
<td>></td>
</tr>
</tbody>
</table>
<div>4行</div>

● 点击某个th,就对该列进行排序
● 可以给表头取别名
● 可以设置某个列是否显示
● 表格下方有一行显示总行数

我们希望表格按如下方式展示:

<table-helper datasource="customers" clumnmap="[{name: 'name'}, {street: 'street'}, {age: 'age'}, {url: 'url', hidden: true}]"></table-helper>

以上,datasource的数据源来自controller中$scope.customers,大致是{name: 'david',street: '1234 anywhere st.',age: 25,url: 'index.html'}这样的格式,具体略去。

columnmap负责给列取别名,并且决定是否显示某个列。

如何实现呢?

directive大致是这样的:

var tablehelper = function(){
var template = '',
link = function(scope, element, attrs){
}
return {
restrict: 'e',
scope: {
columnmap: '=',
datasource: '='
},
link:link,
template:template
}; 
}
angular.module('directivemodule')
.directive('tablehelper', tablehelper); 

具体来说,

首先要监视datasource的变化,一旦有变化,就重新加载表格。

scope.$watchcollection('datasource', render);
//初始化表格
function render(){
if(scope.datasource && scope.datasource.length){
table += tablestart;
table += renderheader();
table += renderrows() + tableend;
//加载统计行
rendertable();
}
} 

加载表格大致分成了三个步骤,加载表头,加载表格体,加载统计行。

//加载头部
function renderheader(){
var tr = '<tr>';
for(var prop in scope.datasource[0]){
//{name: 'david',street: '1234 anywhere st.',age: 25,url: 'index.html'}
//根据原始列名获取别名,并考虑了是否显示列的情况
var val = getcolumnname(prop);
if(val){
//visibleprops存储的是原始列名
visibleprops.push(prop);
tr += '<th>' + val + '</th>';
}
}
tr += '</tr>';
tr = '<thead>' + tr '</thead>';
return tr;
}
//加载行
function renderrows(){
var rows = '';
for(var i = 0, len = scope.datasource.length; i < len; i++){
rows += '<tr>';
var row = scope.datasource[i];
for(var prop in row){
//当前遍历的原始列名是否在visibleprops集合中,该集合存储的是原始列名
if(visibleprops.indexof(prop) > -1){
rows += '<td>' + row[prop] + '</td>';
}
}
rows += '</tr>';
}
rows = '<tbody>' + rows + '</tbody>';
return rows;
}
//加载统计行
function rendertable(){
table += '<br /><div class="rowcount">' + scope.datasource.length + '行</div>';
element.html(table);
table = '';
} 

加载表头的时候,用到了一个根据原始列名获取别名的方法。

//根据原始列名获取列的别名,并考虑是否隐藏列的情况
function getcolumnname(prop){
if(!scope.columnmap) return prop;
//得到[{name: 'name'}]
var val = filtercolumnmap(prop);
if(val && val.length && !val[0].hidden) return val[0][prop];
else return null;
}

在getcolumnname方法中,用到了一个根据原始列名

//比如根据name属性,这里得到[{name: 'name'}]
//[{name: 'name'}, {street: 'street'}, {age: 'age'}, {url: 'url', hidden: true}]
function filtercolumnmap(prop) {
var val = scope.columnmap.filter(function(map) {
if (map[prop]) {
return true;
}
return false;
});
return val;
}

具体代码如下:

(function(){
var tablehelper = fucntion(){
var template = '<div class="tablehelper"></div>',
link = function(scope, element, attrs){
var headercols = [], //表头列们
tablestart = '<table>',
tableend = '</table>',
table = '',
visibleprops = [],//可见列
sortcol = null,//排序列
sortdir =1;
//监视集合
sscope.$watchcollection('datasource', render);
//给表头th绑定事件
wireevents();
//初始化表格
function render(){
if(scope.datasource && scope.datasource.length){
table += tablestart;
table += renderheader();
table += renderrows() + tableend;
//加载统计行
rendertable();
}
}
//给th添加click事件
function wireevents()
{
element.on('click', function(event){
if(event.srcelement.nodename === 'th'){
//获取列的名称
var val = event.srcelement.innerhtml;
//根据列的别名获取原始列名
var col = (scope.columnmap) ? getrawcolumnname(val) : val;
if(col){
//对该列进行排序
sort(col);
}
}
});
}
//给某列排序
function sort(col){
if(sortcol === col){
sortdir = sortdir * -1;
}
sortcol = col;
scope.datasource.sort(function(a,b){
if(a[col] > b[col]) return 1 * sortdir;
if(a[col] < b[col]) return -1 * sortdir;
return 0;
});
//重新加载表格
render();
}
//加载头部
function renderheader(){
var tr = '<tr>';
for(var prop in scope.datasource[0]){
//{name: 'david',street: '1234 anywhere st.',age: 25,url: 'index.html'}
//根据原始列名获取别名,并考虑了是否显示列的情况
var val = getcolumnname(prop);
if(val){
//visibleprops存储的是原始列名
visibleprops.push(prop);
tr += '<th>' + val + '</th>';
}
}
tr += '</tr>';
tr = '<thead>' + tr '</thead>';
return tr;
}
//加载行
function renderrows(){
var rows = '';
for(var i = 0, len = scope.datasource.length; i < len; i++){
rows += '<tr>';
var row = scope.datasource[i];
for(var prop in row){
//当前遍历的原始列名是否在visibleprops集合中,该集合存储的是原始列名
if(visibleprops.indexof(prop) > -1){
rows += '<td>' + row[prop] + '</td>';
}
}
rows += '</tr>';
}
rows = '<tbody>' + rows + '</tbody>';
return rows;
}
//加载统计行
function rendertable(){
table += '<br /><div class="rowcount">' + scope.datasource.length + '行</div>';
element.html(table);
table = '';
}
//根据列的别名获取原始列名
function getrawcolumnname(friendlycol) {
var rawcol;
//columnmap =[{name: 'name'}, {street: 'street'}, {age: 'age'}, {url: 'url', hidden: true}]
scope.columnmap.foreach(function(colmap) {
//{name: 'name'}
for (var prop in colmap) {
if (colmap[prop] === friendlycol) {
rawcol = prop;
break;
}
}
return null;
});
return rawcol;
}
function pushcolumns(rawcol, renamedcol) {
visibleprops.push(rawcol);
scope.columns.push(renamedcol);
}
//比如根据name属性,这里得到[{name: 'name'}]
//[{name: 'name'}, {street: 'street'}, {age: 'age'}, {url: 'url', hidden: true}]
function filtercolumnmap(prop) {
var val = scope.columnmap.filter(function(map) {
if (map[prop]) {
return true;
}
return false;
});
return val;
} 
//根据原始列名获取列的别名,并考虑是否隐藏列的情况
function getcolumnname(prop){
if(!scope.columnmap) return prop;
//得到[{name: 'name'}]
var val = filtercolumnmap(prop);
if(val && val.length && !val[0].hidden) return val[0][prop];
else return null;
}
};
return {
restrict: 'e',
scope: {
columnmap: '=',
datasource: '='
},
link:link,
template:template
};
};
angular.module('directivemodule')
.directive('tablehelper', tablehelper);
}());

以上所述是小编给大家分享的angularjs中的directive自定义一个表格的相关知识,希望对大家有所帮助。