I need to create a directive that acts upon table cells where the table rows are rendered using ng-repeat
-- to that end I have relied in part on this answer to a question entitled "Calling a function when ng-repeat has finished". Unlike that Q&A however, I need to pass in an argument to my directive, and for this I have relied in part on this answer (to a question entitled "Angularjs - Pass argument to directive").
So in my case I've added fixed-column-tooltip
for my directive, and columnselector
as its argument to the <tr>
as follows:
<tr fixed-column-tooltip columnselector=".td-keyField" ng-repeat="trData in trDataWatch">
But when per the second answer, I added what I've learned is an "isolate scope" to my directive, I no longer had access to the original scope necessary as per the first answer:
'use strict';
angular.module('cmt.cases.directives')
.directive('fixedColumnTooltip', function ($timeout) {
return {
restrict: 'A',
scope: {
columnselector: '@'
},
link: function (scope, element, attr) {
if (scope.$last === true) { //undefined because not operating on original scope
...
Is there a way to maintain access to the original scope, but also have access to the columnselector
argument?
Despite being almost completely new to Angular, I am answering my own question but still want additional answers in case the way I solved my problem is not considered "idiomatic" Angular.
Specifically, instead of using an isolate scope, I leveraged the third attrs
(attributes) link/function argument in my code below, to otherwise get the new columnselector
attribute to the html along with my directive. Is this a generally accepted practice?
'use strict';
angular.module('cmt.cases.directives')
.directive('fixedColumnTooltip', function ($timeout) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
if (scope.$last === true) {
$timeout(function () {
element.parent().find(attrs.columnselector).each(function() {
var td = $(this);
var span = td.find('span');
if (span.width() > td.width()){
span.attr('data-toggle','tooltip');
span.attr('data-placement','right');
span.attr('title', span.html());
}
});
});
}
}
}
});
ADDENDUM: As you can see from comments I have not been able to get the code from this answer to work, despite trying it a couple of different ways. If I'm doing something wrong with regard to incorporating that answer please let me know.
In the meantime I have found another way to do it, but this is almost certainly more of a "code smell" than leveraging the attrs
argument. Specifically I have discovered that I can use an isolate scope, and then access that scope's $parent
scope attribute. Then I would begin my code as follows, but I am not advocating this, but rather am just noting it as it seems that TMTOWTDI (there's more than one way to do it) certainly applies to Angular:
'use strict';
angular.module('cmt.cases.directives')
.directive('fixedColumnTooltip', function ($timeout) {
return {
restrict: 'A',
scope: {
columnselector: '@'
},
link: function (scope, element, attrs) {
if (scope.$parent.$last === true) {
$timeout(function () {
element.parent().find(scope.columnselector).each(function() {
...