首页 > 编程 > JavaScript > 正文

AngularJS中的Directive自定义一个表格

2019-11-20 10:42:17
字体:
来源:转载
供稿:网友

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

● 表格结构

<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自定义一个表格的相关知识,希望对大家有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表