First of all, the need for a table:
Table structure
<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 line </div>
Click on an th and sort the column
You can alias a table header
You can set whether a column displays
One row below the table shows the total number of rows
We want the form to be shown as follows:
<table-helper datasource="customers" clumnmap="[{name: 'Name'}, {street: 'Street'}, {age: 'Age'}, {url: 'URL', hidden: true}]"></table-helper>
Above, the DataSource data source is from controller $scope.customers, roughly {name: ' David ', street: ' 1234 Anywhere St. ', Age:25,url: ' Index.html '} Such a format, specifically omitted.
Columnmap is responsible for the alias of the column and determines whether a column is displayed.
How to achieve it?
The directive is roughly like this:
var tablehelper = function () {
var template = ',
link = function (scope, element, Attrs) {
} return
{
R Estrict: ' E ',
scope: {
columnmap: ' = ',
datasource: ' = '
},
Link:link,
template:template
};
}
Angular.module (' Directivemodule ')
Specifically,
First, monitor the datasource changes and reload the table as soon as it changes.
Scope. $watchCollection (' datasource ', render);
Initialize table
function render () {
if (Scope.datasource && scope.datasource.length) {
table = = Tablestart;
Table + = Renderheader ();
Table + + renderrows () + tableend;
Load statistic row
rendertable ();
}
The loading table is roughly divided into three steps, loading the table header, loading the table body, loading the statistic rows.
// Load the header
function renderHeader () {
var tr = '<tr>';
for (var prop in scope.datasource [0]) {
// {name: 'David', street: '1234 Anywhere St.', age: 25, url: 'index.html'}
// Get the alias based on the original column name, and consider whether to display the column
var val = getColumnName (prop);
if (val) {
// visibleProps stores the original column names
visibleProps.push (prop);
tr + = '<th>' + val + '</ th>';
}
}
tr + = '</ tr>';
tr = '<thead>' + tr '</ thead>';
return tr;
}
// Load rows
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) {
// The original column name being traversed is in the visibleProps collection, which stores the original column name
if (visibleProps.indexOf (prop)> -1) {
rows + = '<td>' + row [prop] + '</ td>';
}
}
rows + = '</ tr>';
}
rows = '<tbody>' + rows + '</ tbody>';
return rows;
}
// Load statistics rows
function renderTable () {
table + = '<br /> <div class = "rowCount">' + scope.datasource.length + 'row </ div>';
element.html (table);
table = '';
}
When loading the header, a method is used to get an alias based on the original column name.
Gets the alias of the column based on the original column name and considers whether to hide the condition of the column
function getColumnName (prop) {
if (!scope.columnmap) return prop;
Get [{name: ' name '}]
var val = filtercolumnmap (prop);
if (Val && val.length &&!val[0].hidden) return Val[0][prop];
else return null;
}
In the getColumnName method, you use a name from the original column
For example, according to the Name property, this gets [{name: ' name '}]
//[{name: ' name '}, {street: ' street '}, {age: ' age '}, {url: ' url ', hidden:true}]< C10/>function Filtercolumnmap (prop) {
var val = scope.columnmap.filter (function (map) {
if (Map[prop)) { return
true;
}
return false;
});
return val;
}
The specific code is as follows:
(function () {
var tableHelper = fucntion () {
var template = '<div class = "tableHelper"> </ div>',
link = function (scope, element, attrs) {
var headerCols = [], // Table header columns
tableStart = '<table>',
tableEnd = '</ table>',
table = '',
visibleProps = [], // visible columns
sortCol = null, // sort
sortDir = 1;
// watch collection
sscope. $ watchCollection ('datasource', render);
// Bind event to table header th
wireEvents ();
// Initialize the form
function render () {
if (scope.datasource && scope.datasource.length) {
table + = tableStart;
table + = renderHeader ();
table + = renderRows () + tableEnd;
// Load statistics rows
renderTable ();
}
}
// Add a click event to th
function wireEvents ()
{
element.on ('click', function (event) {
if (event.srcElement.nodeName === 'TH') {
// Get the name of the column
var val = event.srcElement.innerHTML;
// Get the original column name based on the alias of the column
var col = (scope.columnmap)? getRawColumnName (val): val;
if (col) {
// sort the column
sort (col);
}
}
});
}
// sort a column
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;
});
// Reload the table
render ();
}
// Load the header
function renderHeader () {
var tr = '<tr>';
for (var prop in scope.datasource [0]) {
// {name: 'David', street: '1234 Anywhere St.', age: 25, url: 'index.html'}
// Get the alias based on the original column name, and consider whether to display the column
var val = getColumnName (prop);
if (val) {
// visibleProps stores the original column names
visibleProps.push (prop);
tr + = '<th>' + val + '</ th>';
}
}
tr + = '</ tr>';
tr = '<thead>' + tr '</ thead>';
return tr;
}
// Load rows
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) {
// The original column name being traversed is in the visibleProps collection, which stores the original column name
if (visibleProps.indexOf (prop)> -1) {
rows + = '<td>' + row [prop] + '</ td>';
}
}
rows + = '</ tr>';
}
rows = '<tbody>' + rows + '</ tbody>';
return rows;
}
// Load statistics rows
function renderTable () {
table + = '<br /> <div class = "rowCount">' + scope.datasource.length + 'row </ div>';
element.html (table);
table = '';
}
// Get the original column name based on the alias of the column
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);
}
// For example, according to the name attribute, here is [{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;
}
// Get the alias of the column according to the original column name and consider whether to hide the column
function getColumnName (prop) {
if (! scope.columnmap) return prop;
// Get [{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);
} ());
The above is a small set to share the ANGULARJS in the directive custom a form of knowledge, I hope to help you.