I'm running into weird behaviour on IE11 when filtering tabular data using Angular.
<ng-container *ngFor="let item of items; trackBy: trackByFn">
<tr>...</tr>
<tr *ngIf="showDetails(item)">...</tr>
</ng-container>
What happens is that some rows are not properly rendered when the items
change (i.e. when searching or filtering data) in IE11:
As you can see in the image above, the <tr>
element is there, and so is its content. The green rows render just fine, but the red one clearly isn't. As soon as I hover the empty row, its content will appear again.
The issue is probably caused by the ng-container
wrapping each two rows, IE can't handle this properly. Any ideas to fix this?
Removing the spaces in <td>
elements didn't resolve the issue, unfortunately. However, I did managed to get it working by creating a custom *ngIf
directive for Internet Explorer only, which forces the browser to re-render the table:
For those who run into the same issue, here is the code:
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
/**
* Add the template content to the DOM when the condition is true for IE browsers only.
*/
@Directive({
selector: '[appIfIE]'
})
export class IfIeDirective {
private hasView = false;
private isIE = navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > -1;
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef
) {}
@Input() set appIfIE(condition: boolean) {
if (!this.isIE && !this.hasView) {
this.createView();
} else if (this.isIE && condition && !this.hasView) {
this.createView();
} else if (this.isIE && !condition && this.hasView) {
this.clearView();
}
}
createView() {
this.viewContainer.createEmbeddedView(this.templateRef);
this.hasView = true;
}
clearView() {
this.viewContainer.clear();
this.hasView = false;
}
}
... and apply the directive where you see fit:
<tbody *appIfIE="!loading">
Cheers!