I have created a custom Angular element directive that displays and hides a loading indicator based on a condition from a service call. The directive is used as an element within another element. While the directive itself works correctly, the issue is that the content within the applied element does not hide.
Below is my directive code:
export interface ILoadingIndicatorAttr extends ng.IAttributes {
efpLoadingIndicator: string;
}
export interface ILoadingIndicatorscope extends ng.IScope {
loading: boolean;
}
export class LoadingIndicator implements ng.IDirective {
public restrict: string = 'A';
public replace: boolean = true;
static $inject = ["$compile", "$templateRequest", "$timeout"];
constructor(public _compile: ng.ICompileService, private templateService: ng.ITemplateRequestService, private timeout: ng.ITimeoutService) {
};
link = (scope: ILoadingIndicatorscope, element: ng.IAugmentedJQuery, attrs: ILoadingIndicatorAttr, ngModel: ng.INgModelController): void => {
var tempThis = this;
var templateUrl: string = 'app/modules/common/directives/loadingIndicator/loadingIndicator.tmpl.html';
attrs.$observe('efpLoadingIndicator', () => {
if (attrs.efpLoadingIndicator == "true") {
this.timeout(() => {
if (attrs.efpLoadingIndicator == "true") {
scope.loading = true;
tempThis.resolveTemplate(templateUrl).then((html: ng.IAugmentedJQuery) => {
tempThis._compile(html)(scope).appendTo(element);
});
}
else {
scope.loading = false;
}
}, 1000);
}
else {
scope.loading = false;
}
});
}
resolveTemplate = (templateUrl: string): ng.IPromise<ng.IAugmentedJQuery> => {
return this.templateService(templateUrl).then((html: string) => {
return angular.element(html);
});
}
}
Here is how you can apply it:
<div efp-loading-indicator={{vm.isLoading}}>
<select> </select>
</div>
The goal is to hide the content of the div when the loading indicator is visible and show the content when the loading indicator is hidden. Avoiding the use of ng-show on child elements allows for reusability of this directive.