Reputation: 5343
I am building a tabs component and in its headers i added a ripple component that attaches a class and does the animation as seen in code below.
However even though it works in all my other components i.e buttons seems that it fails to work when used inside an ngTemplateOutlet context. Perhaps i am doing something wrong. Any tips welcome.
tabsComponentTemplate
<div class="nui-tab-group">
<ng-template #defaultTabsHeader let-tabs="tabs">
<ul class="nui-tab-group-buttons" *ngIf="tabs">
<li class="tab-button"
[ngClass]="{selected: tab.selected}"
(click)="selectedTab(tab)"
ripple-c
*ngFor="let tab of tabs">{{ tab.title }}
</li>
</ul>
</ng-template>
<ng-container *ngTemplateOutlet="headerTemplate || defaultTabsHeader; context: tabsContext"></ng-container>
<ng-content></ng-content>
</div>
ripple component main part
@HostListener('click', ['$event', '$event.currentTarget'])
click(event, element) {
if (this.rippleStyle === 'expand') {
let ripple = document.createElement('span'),
rect = element.getBoundingClientRect(),
radius = Math.max(rect.height, rect.width),
left = event.pageX - rect.left - radius / 2 - document.body.scrollLeft,
top = event.pageY - rect.top - radius / 2 - document.body.scrollTop;
ripple.className = 'expand-ripple-effect animate';
ripple.style.width = ripple.style.height = radius + 'px';
ripple.style.left = left + 'px';
ripple.style.top = top + 'px';
ripple.addEventListener('animationend', () => {
element.removeChild(ripple);
});
element.appendChild(ripple);
}
}
Upvotes: 1
Views: 1773
Reputation: 214165
The main reason for this is that your list is rerendered every time change detection happens because you're passing new object to context
every time:
get tabsContext() {
return {
tabs: this.tabs
}
}
NgTemplateOutlet directive sees this changes and clears templateю
Use prepared data for template
tabsContext: any;
ngAfterContentInit (): void {
...
this.tabsContext = {
tabs: this.tabs
}
}
See also similar case
Upvotes: 1