I am having a problem updating css on an element in Angular. I have a div
that contains elements generated by ng-repeat
. The div
containing these elements has a set height and has the ng-scrollbars
directive attached to it. ng-scrollbars
creates a nice scrollbar inside a div
when the elements in the div
exceed the height of the their container. To do this it creates nested internal divs. So in this case, if the height of the nested internal divs is larger than their container then a scrollbar is made so that you can scroll through the elements.
So lets say I add or remove items to the ng-repeat
list. When this happens I would like additional css to be added to the top level div only if the internal div made by ng-scrollbars
exceed the height of the top level div. (the height of the internal div is the actual height of the ng-repeat
list because it contains the ng-repeat
elements)
To do this I created two directives, one that broadcasts an event and one that receives it. The one that broadcasts the event is attached to every ng-repeat
element and is broadcasted when the element is created or destroyed. This is to check when changes happen to the ng-repeat
list.
The one that receives the broadcast is attached to the top level div
container (the one that contains the div made by ng-scrollbar
) and checks its height against the internal div made by ng-scrollbar
, if the height of the internal div is greater than the top level div then add some css.
I'm sorry if this seems confusing, here's my code doing this with comments attached that I hope explain it better:
app.directive('gtScrollLb', function () {
return {
restrict: 'A',
link: function (scope, elem, attrs) { //elem is the top level container of the ng-repeat elements
var scrollDiv = elem.children()[0]; //this is an internal div created by ng-scrollbars
var anotherScrollDiv = $(scrollDiv).children("#" + $(scrollDiv).attr("id") + "_container"); //another internal div created by ng-scrollbars
var id = attrs.gtScrollLb;
scope.$on(id + "-repeat-change",
function(newVal, oldVal) {
//check if ng-scrollbar div that now contains the ng-repeat elements
//has a greater height than the top level container
if ($(anotherScrollDiv).height() >= elem.height()) {
elem.css("border-bottom", "1px solid darkgrey");
} else {
elem.css("border-bottom", "");
}
}
);
}
};
});
app.directive('gtRepeatable', function () {
return {
restrict: 'A',
link: function (scope, elem, attrs) {
var id = attrs.gtRepeatable;
scope.$emit(id + "-repeat-change"); //event that item has been added by ng-repeat
var parent = scope.$parent;
elem.bind("$destroy",function(){
parent.$broadcast(id + "-repeat-change");//event that item has been destroyed by ng-repeat
});
}
}
});
The problem is that the ng-repeat
elements are added and destroyed before the height of their internal container is determined again. So the height being checked when the change event is fired is actually the old height of the internal container.
I need to somehow check the new height. I have been trying to solve this for a long time now, any help would be greatly appreciated.
Edit
In a nutshell, I need an even to fire or $watch to happen after ng-repeat has finished and the DOM has rendered. The problem I'm having here only happens because the event is fired before the DOM is rendered.
Edit 2
For @vittore who flagged this as a duplicate. If you had actually read my question in detail you would see that the one you proposed as the duplicate had nothing to do with my actual problem. There is no problem with ng-scrollbars
here. ng-scrollbars
is working fine. But it was necessary to include it in the description because it effects how I'm going about solving my problem.