AngularJS中自定义有关一个表格的Directive
本篇体验在AngularJS中自定义一个有关表格的Directive。表格的需求包括:
● 表格结构
<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的更多相关文章
- [Swift通天遁地]二、表格表单-(3)在表格中嵌套另一个表格并使Cell的高度自适应
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- angularJs中自定义directive的数据交互
首先放官方文档地址:https://docs.angularjs.org/guide/directive 就我对directive的粗浅理解,它一般用于独立Dom元素的封装,应用场合为控件重用和逻辑模 ...
- 关于angularjs 中自定义过滤器
包子认为,在angularjs中,经常需要用到自定义过滤器,来过滤相应的功能,自定义过滤器非常的简单,我就直接贴代码啦 其中input就是你需要进行操作的对象,,,用法就直接就是 是不是很easy.. ...
- AngularJS中自定义过滤器
AngularJS中为我们提供了一些内置的过滤器,这里列举一些自定义过滤器的场景. 自定义过滤器,不带参赛 //过滤 不带参赛 app.filter('ordinal', function () { ...
- angularJS中自定义指令
学习了angularJS一周,但是大部分时间被自定义指令占用了.博主表示自学互联网好心塞的,发现问题的视觉很狭窄,这比解决问题要更难.这篇文章首先介绍了自定义,然后介绍了在使用自定义指令遇到的问题. ...
- AngularJS中使用$parse或$eval在运行时对Scope变量赋值
在"AngularJS中自定义有关一个表格的Directive"中自定义了一个有关表格的Direcitve,其表格的表现方式是这样的: <table-helper datas ...
- angularJS中directive与controller之间的通信
当我们在angularJS中自定义了directive之后需要和controller进行通讯的时候,是怎么样进行通讯呢? 这里介绍3种angular自定义directive与controller通信的 ...
- AngularJS中的指令
欢迎大家讨论与指导 : ) 前言 当AngularJS中的内置指令不能满足我们的需求,或者当我们需要创建一个能够用于多个AngularJS程序的自包含的功能单元时,我们应该创建自定义指令来满足需求. ...
- AngularJS中实现Model缓存
在AngularJS中如何实现一个Model的缓存呢? 可以通过在Provider中返回一个构造函数,并在构造函数中设计一个缓存字段,在本篇末尾将引出这种做法. 一般来说,Model要赋值给Scope ...
随机推荐
- Ex 6_16 旧货销售问题_第七次作业
即可 子问题定义:定义数组B(S,j),其中 B(S,j)表示在子集S中结束位置为j的子问题的最大收益值,其中j的前一个地点有两种情况,第一种情况是某个拍卖会 另一种情况是从家里出发. 递归关系: 初 ...
- citySelect省市区jQuery联动插件
参考地址:http://blog.csdn.net/qq_33556185/article/details/50704446 参考地址:http://www.lanrenzhijia.com/jque ...
- OCM_第七天课程:Section3 —》数据库可用性
注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...
- java lambda 的用法
一.打印数组 String[] s = "fdsfsdfds".split(""); Stream<String> str = Stream.of( ...
- jquery----数据增删改
简单版本 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...
- hdu2838树状数组解逆序
离散化和排序后的序号问题搞得我实在是头痛 不过树状数组解逆序和偏序一类问题真的好用 更新:hdu的数据弱的真实,我交上去错的代价也对了.. 下面的代码是错的 /* 每个点的贡献度=权值*在这个点之前的 ...
- SPLAY,LCT学习笔记(五)
这一篇重点探讨LCT的应用 例:bzoj 2631 tree2(国家集训队) LCT模板操作之一,利用SPLAY可以进行区间操作这一性质对维护懒惰标记,注意标记下传顺序和如何下传 #include & ...
- python3 + selenium 使用 JS操作页面滚动条
js2 = "window.scrollTo(0,0);" #括号中为坐标 当不知道需要的滚动的坐标大小时: weizhi2 = driver.find_element_by_id ...
- String对象的常用属性和方法
属性 描述 length 在大多数情况下返回字符串中的字符数 方法 描述 toUpperCase() 将字符串修改为大写字母 toLowerCase() 将字符串修改为小写字母 charAt() 以索 ...
- 【Java】 剑指offer(24) 反转链表
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头 ...