3

I'm trying to create a loading indicator/overlay in Angular2 that I can add to any container div. When a dynamic boolean property like isLoading changes, it should grey out the div and show a spinning indicator, and disappear again after the property changes back.

I got a working solution:

@Component({
  selector: 'loading-overlay',
  styleUrls: ['...'],
  template: `
        <div class="bg-loading" *ngIf="isLoading">
          <h3><span class="glyphicon glyphicon-refresh spinning"></span></h3>
        </div>`
})
export class LoadingOverlay {
  @Input()    
  isLoading: boolean;
}

And usage:

<div> <!-- container for whatever -->
  <loading-overlay [isLoading]="dynamicProp"></loading-overlay>
  <!-- ... other content -->
</div>

So far so good, but this is hard to get right with styling for different use cases, mostly to make the margins/paddings look good in different containers.

So I want to make this whole thing into an attribute directive like so:

<div loading-overlay="dynamicProp"> <!-- container for whatever -->
  <!-- content ... -->
</div>

I'm pretty sure this should be easy, but I can't find anything useful in the docs or via googling. It feels like I should dynamically add/remove the overlay div, but I'm not sure if this is the right approach, or even how to do it.

user1787764
  • 31
  • 1
  • 2
  • What's the problem with styling? A directive doesn't have a view, therefore I don't think this is the right approach. – Günter Zöchbauer Jun 02 '16 at 06:23
  • The loading overlay (component, so the working version) had some padding/margins to inset it in the containing div, which is hard to get right if in one case it's a large table that should be covered and sometimes only a narrow sidebar. So my idea was to make it into a directive that just fills the whole div that the directive is applied to, which is what I can't get to work. – user1787764 Jun 02 '16 at 07:41
  • If you think you can do it with a directive, why do you think you can't with a component? How would the expected result look different when done with a directive. What do you think a directive can achieve a component can't? – Günter Zöchbauer Jun 02 '16 at 07:45

1 Answers1

2

We created a similar thing in a project, however we stuck to the element-directive approach. Not sure if/what benefits you would get by converting it to a directive. I think it would even make it harder.

Our solution was for sure no the cleanest approach, here's roughly what we did which worked well for us so far:

When the components state toggles to "is showing" the component will inspect its parent element for size information (height/width) and apply these values to itself.

for positioning we use the simple: container-element with 0x0px positionioned at pos 0/0 of the parent (relative), inside that there is the real overlay (positioned fixed, size set dynamically as described above).

For padding/margin i'm currently not sure if we had to do lots of fixes, i think it shouldn't be too difficult to get around that by querying the parent element.

We even re-called our "calculate size" method a few times after the component is shown: the reason is that the element which we wanted to overlay sometimes changed its size during the loading process. Imagine for example a table (has 3 lines), gets reloaded, expands to 6 lines but for some reason we aren't done loading so the overlay should still be shown, but we want the overlay to automatically cover these newly added lines as well.

NoUsername
  • 693
  • 6
  • 20