I have been implementing a pattern in my application to delay loading certain expensive DOM elements until they are needed. The pattern involves using conditional logic like this:
<div ng-if="someCondition || everShown" ng-show="someCondition">
This ensures that the element is only added to the DOM when someCondition is true and remains there thereafter. However, I noticed a lot of repetitive code and decided to create a directive to streamline this process.
Here is my attempt at creating the directive:
export function IfEverShown($parse: angular.IParseService): angular.IDirective {
return {
restrict: "A",
compile: function(element: angular.IAugmentedJQuery,
attributes: angular.IAttributes) {
if (!attributes["ngShow"]) {
return;
}
element.attr("ng-if", "everShown");
return {
pre: function(scope: angular.IScope) {
scope["everShown"] = false;
attributes.$observe('ngShow', function (expr) {
scope.$watch(function () {
return $parse(<any> expr)(scope);
}, function (value) {
if (value) {
scope["everShown"] = true;
}
});
});
}
};
}
};
}
To use the directive, you would do:
<div ng-show="someCondition" if-ever-shown>
However, despite changing the ng-if value in the DOM as expected, Angular seems to ignore the changes. The element is always present in the DOM if there was no previous ng-if, and observed even after it has been changed from its previous value.
How can I achieve the desired behavior? Is it possible to modify an ngIf from a directive? Alternatively, is there another way to ensure that the element is not added to the DOM until the ng-show condition has been true at least once?
Thank you!