I\'m using angular.js and (for the sake of argument) bootstrap. Now I need to iterate on \"things\" and display them in \'\'rows\'\' :
I recommend a directive for a couple of reasons:
Here is a suggested element directive:
In the implementation I used code similar to your server-side example:
myApp.directive('rowGenerator', function() {
var rowTemplate = '',
colTemplate = '';
return {
restrict: 'E',
// use '=' for colCount instead of '@' so that we don't
// have to use attr.$observe() in the link function
scope: { rowData: '=', colCount: '='},
link: function(scope, element) {
// To save CPU time, we'll just watch the overall
// length of the rowData array for changes. You
// may need to watch more.
scope.$watch('rowData.length', function(value) {
var html = rowTemplate;
for(var i=0; i < scope.rowData.length; i++) {
html += colTemplate + scope.rowData[i].key + '';
if (i % scope.colCount == scope.colCount - 1) {
html += '' + rowTemplate;
}
}
html += 'Data:
$scope.things = [
{key: 'one'},
{key: 'two'},
{key: 3},
{key: 4},
{key: 'five'},
{key: 'six'},
{key: 77},
{key: 8}
];
Fiddle
To be efficient, the directive as shown only looks for changes to the length of the rowData (i.e., things) array. If you want to have the directive update the view if the value of one of the array elements changes, you'll need a more expensive $watch:
scope.$watch('rowData', function(value){ ... }, true)
The true at the end does "shallow" dirty checking ("compares the object for equality rather than for reference) -- see docs.
There's one thing I don't like about the directive -- it needs to know that rowData entries have a property with name key:
html += colTemplate + scope.rowData[i].key + '