Skip to content
This repository was archived by the owner on Feb 2, 2025. It is now read-only.

Commit 3c3a023

Browse files
committed
This time for sure, I corrected this bug (not nicely, but still) #43
1 parent ff7d701 commit 3c3a023

6 files changed

+82
-80
lines changed

dist/angular-datatables.js

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -359,16 +359,12 @@
359359
}(angular));
360360
(function (angular) {
361361
'use strict';
362-
angular.module('datatables.directive', [
363-
'datatables.options',
364-
'datatables.util'
365-
]).directive('datatable', [
362+
angular.module('datatables.directive', ['datatables.options']).directive('datatable', [
366363
'DT_DEFAULT_OPTIONS',
367364
'$timeout',
368365
'$DTBootstrap',
369366
'DTLoadingTemplate',
370-
'$DTPropertyUtil',
371-
function (DT_DEFAULT_OPTIONS, $timeout, $DTBootstrap, DTLoadingTemplate, $DTPropertyUtil) {
367+
function (DT_DEFAULT_OPTIONS, $timeout, $DTBootstrap, DTLoadingTemplate) {
372368
var $loading = angular.element(DTLoadingTemplate.html), _showLoading = function ($elem) {
373369
$elem.after($loading);
374370
$elem.hide();
@@ -380,11 +376,8 @@
380376
$scope.$emit('event:dataTableLoaded', { id: $elem.attr('id') });
381377
return oTable;
382378
}, _doRenderDataTable = function ($elem, options, $scope) {
383-
// Add $timeout to be sure that angular has finished rendering before calling datatables
384-
$timeout(function () {
385-
_hideLoading($elem);
386-
_renderDataTableAndEmitEvent($elem, options, $scope);
387-
}, 0, false);
379+
_hideLoading($elem);
380+
return _renderDataTableAndEmitEvent($elem, options, $scope);
388381
},
389382
/**
390383
* Check if the given table is a using DataTable version 1.9.4
@@ -424,7 +417,10 @@
424417
return {
425418
options: options,
426419
render: function ($scope, $elem) {
427-
_doRenderDataTable($elem, this.options, $scope);
420+
// Add $timeout to be sure that angular has finished rendering before calling datatables
421+
$timeout(function () {
422+
_doRenderDataTable($elem, this.options, $scope);
423+
}, 0, false);
428424
}
429425
};
430426
};
@@ -438,12 +434,30 @@
438434
return {
439435
options: options,
440436
render: function ($scope, $elem) {
441-
var _this = this, parentScope = $scope.$parent, dataProp = $DTPropertyUtil.findDataPropFromScope(parentScope);
442-
if (parentScope[dataProp].length === 0) {
443-
_doRenderDataTable($elem, _this.options, $scope);
437+
var _this = this, expression = $elem.find('tbody').html(),
438+
// Find the resources from the comment <!-- ngRepeat: item in items --> displayed by angular in the DOM
439+
// This regexp is inspired by the one used in the "ngRepeat" directive
440+
match = expression.match(/^\s*.+\s+in\s+(\w*)\s*/), ngRepeatAttr = match[1];
441+
if (!match) {
442+
throw new Error('Expected expression in form of "_item_ in _collection_[ track by _id_]" but got "{0}".', expression);
444443
}
445-
$scope.$on(DT_DEFAULT_OPTIONS.lastRowKey, function () {
446-
_doRenderDataTable($elem, _this.options, $scope);
444+
var oTable, firstCall = true, alreadyRendered = false;
445+
$scope.$parent.$watchCollection(ngRepeatAttr, function () {
446+
// This condition handles the case the array is empty
447+
if (firstCall) {
448+
firstCall = false;
449+
$timeout(function () {
450+
if (!alreadyRendered) {
451+
oTable = _doRenderDataTable($elem, _this.options, $scope);
452+
alreadyRendered = true;
453+
}
454+
}, 1000, false); // Hack I'm not proud of... Don't know how to do it otherwise...
455+
} else {
456+
$timeout(function () {
457+
oTable = _doRenderDataTable($elem, _this.options, $scope);
458+
alreadyRendered = true;
459+
}, 0, false);
460+
}
447461
});
448462
}
449463
};
@@ -622,14 +636,15 @@
622636
};
623637
}
624638
]).directive('dtRows', [
625-
'$rootScope',
626-
'DT_DEFAULT_OPTIONS',
627-
function ($rootScope, DT_DEFAULT_OPTIONS) {
639+
'$log',
640+
function ($log) {
641+
var hasWarned;
628642
return {
629643
restrict: 'A',
630-
link: function ($scope) {
631-
if ($scope.$last === true) {
632-
$rootScope.$broadcast(DT_DEFAULT_OPTIONS.lastRowKey);
644+
link: function () {
645+
if (!hasWarned) {
646+
$log.warn('As of v0.1.0, the directive "dtRows" is deprecated. This directive is no longer needed. It will be removed completly from v0.2.0');
647+
hasWarned = true;
633648
}
634649
}
635650
};
@@ -930,7 +945,6 @@
930945
(function (angular) {
931946
'use strict';
932947
angular.module('datatables.options', []).constant('DT_DEFAULT_OPTIONS', {
933-
lastRowKey: 'datatable:lastRow',
934948
dom: 'lfrtip',
935949
sAjaxDataProp: '',
936950
aoColumns: []
@@ -998,14 +1012,6 @@
9981012
result = angular.copy(target);
9991013
}
10001014
return result;
1001-
},
1002-
findDataPropFromScope: function (scope) {
1003-
for (var prop in scope) {
1004-
if (prop.indexOf('$', 0) !== 0 && scope.hasOwnProperty(prop) && angular.isArray(scope[prop])) {
1005-
return prop;
1006-
}
1007-
}
1008-
throw new Error('Cannot find the data property from the scope');
10091015
}
10101016
};
10111017
});

dist/angular-datatables.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/angular-datatables.directive.js

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
(function(angular) {
22
'use strict';
33

4-
angular.module('datatables.directive', ['datatables.options', 'datatables.util']).
5-
directive('datatable', function(DT_DEFAULT_OPTIONS, $timeout, $DTBootstrap, DTLoadingTemplate, $DTPropertyUtil) {
4+
angular.module('datatables.directive', ['datatables.options']).
5+
directive('datatable', function(DT_DEFAULT_OPTIONS, $timeout, $DTBootstrap, DTLoadingTemplate) {
66
var $loading = angular.element(DTLoadingTemplate.html),
77
_showLoading = function ($elem) {
88
$elem.after($loading);
@@ -16,11 +16,8 @@
1616
$scope.$emit('event:dataTableLoaded', { id: $elem.attr('id') });
1717
return oTable;
1818
}, _doRenderDataTable = function($elem, options, $scope) {
19-
// Add $timeout to be sure that angular has finished rendering before calling datatables
20-
$timeout(function() {
21-
_hideLoading($elem);
22-
_renderDataTableAndEmitEvent($elem, options, $scope);
23-
}, 0, false);
19+
_hideLoading($elem);
20+
return _renderDataTableAndEmitEvent($elem, options, $scope);
2421
},
2522
/**
2623
* Check if the given table is a using DataTable version 1.9.4
@@ -64,7 +61,10 @@
6461
return {
6562
options: options,
6663
render: function ($scope, $elem) {
67-
_doRenderDataTable($elem, this.options, $scope);
64+
// Add $timeout to be sure that angular has finished rendering before calling datatables
65+
$timeout(function() {
66+
_doRenderDataTable($elem, this.options, $scope);
67+
}, 0, false);
6868
}
6969
};
7070
};
@@ -80,13 +80,35 @@
8080
options: options,
8181
render: function ($scope, $elem) {
8282
var _this = this,
83-
parentScope = $scope.$parent,
84-
dataProp = $DTPropertyUtil.findDataPropFromScope(parentScope);
85-
// if (parentScope[dataProp].length === 0) {
86-
// _doRenderDataTable($elem, _this.options, $scope);
87-
// }
88-
$scope.$on(DT_DEFAULT_OPTIONS.lastRowKey, function () {
89-
_doRenderDataTable($elem, _this.options, $scope);
83+
expression = $elem.find('tbody').html(),
84+
// Find the resources from the comment <!-- ngRepeat: item in items --> displayed by angular in the DOM
85+
// This regexp is inspired by the one used in the "ngRepeat" directive
86+
match = expression.match(/^\s*.+\s+in\s+(\w*)\s*/),
87+
ngRepeatAttr = match[1];
88+
89+
if (!match) {
90+
throw new Error('Expected expression in form of "_item_ in _collection_[ track by _id_]" but got "{0}".', expression);
91+
}
92+
93+
var oTable,
94+
firstCall = true,
95+
alreadyRendered = false;
96+
$scope.$parent.$watchCollection(ngRepeatAttr, function () {
97+
// This condition handles the case the array is empty
98+
if (firstCall) {
99+
firstCall = false;
100+
$timeout(function() {
101+
if (!alreadyRendered) {
102+
oTable = _doRenderDataTable($elem, _this.options, $scope);
103+
alreadyRendered = true;
104+
}
105+
}, 1000, false); // Hack I'm not proud of... Don't know how to do it otherwise...
106+
} else {
107+
$timeout(function() {
108+
oTable = _doRenderDataTable($elem, _this.options, $scope);
109+
alreadyRendered = true;
110+
}, 0, false);
111+
}
90112
});
91113
}
92114
};
@@ -269,12 +291,14 @@
269291
}
270292
};
271293
}).
272-
directive('dtRows', function ($rootScope, DT_DEFAULT_OPTIONS) {
294+
directive('dtRows', function ($log) {
295+
var hasWarned;
273296
return {
274297
restrict: 'A',
275-
link: function($scope) {
276-
if ($scope.$last === true) {
277-
$rootScope.$broadcast(DT_DEFAULT_OPTIONS.lastRowKey);
298+
link: function() {
299+
if (!hasWarned) {
300+
$log.warn('As of v0.1.0, the directive "dtRows" is deprecated. This directive is no longer needed. It will be removed completly from v0.2.0');
301+
hasWarned = true;
278302
}
279303
}
280304
};

src/angular-datatables.options.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
'use strict';
33
angular.module('datatables.options', []).
44
constant('DT_DEFAULT_OPTIONS', {
5-
// Event key emit when the last element of the list is rendered when using the angular way
6-
lastRowKey: 'datatable:lastRow',
75
// Default dom
86
dom: 'lfrtip',
97
// Default ajax properties. See http://legacy.datatables.net/usage/options#sAjaxDataProp

src/angular-datatables.util.js

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,6 @@
2828
result = angular.copy(target);
2929
}
3030
return result;
31-
},
32-
/**
33-
* Find the first array data property from the given scope.
34-
* It
35-
* @param scope the scope
36-
* @returns {string} the property
37-
*/
38-
findDataPropFromScope: function (scope) {
39-
for (var prop in scope) {
40-
if (prop.indexOf('$', 0) !== 0 && scope.hasOwnProperty(prop) && angular.isArray(scope[prop])) {
41-
return prop;
42-
}
43-
}
44-
throw new Error('Cannot find the data property from the scope');
4531
}
4632
};
4733
});

test/spec/angular-datatables.util.spec.js

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,5 @@ describe('datatables.service', function () {
5252
expect($DTPropertyUtil.overrideProperties(source, null)).toEqual(source);
5353
});
5454
});
55-
56-
describe(', when fetching the data array from the scope,', function () {
57-
it('should fetch the correct data array', inject(function ($rootScope) {
58-
var scope = $rootScope.$new();
59-
scope.persons = ['foo', 'bar'];
60-
expect($DTPropertyUtil.findDataPropFromScope(scope)).toBe('persons');
61-
}));
62-
it('should throw an error if the scope does not contain any array', inject(function ($rootScope) {
63-
var scope = $rootScope.$new();
64-
expect(function() {$DTPropertyUtil.findDataPropFromScope(scope);}).toThrow(new Error('Cannot find the data property from the scope'));
65-
}));
66-
});
6755
});
6856
});

0 commit comments

Comments
 (0)