I am trying to develop a carousel.
The desired end result should be that the developer would simply write the entire markup in one place (let's say in app.component.html
) with only an options
property and then, the carousel would take over.
Problem is that from carousel.component
I need to set some properties on carousel-item.component
(properties that app.component
should have nothing to do with... but all the markup is in app.component.html
).
How can I achieve this?
app.component.html:
<carousel [options]="myOptions">
<carousel-item *ngFor="let item of items">
<img [src]="item.image" alt="" />
</carousel-item>
</carousel>
<hr />
<carousel [options]="myOptions2">
<carousel-item *ngFor="let item of items">
<img [src]="item.image" alt="" />
</carousel-item>
</carousel>
carousel.component.html:
<div class="carousel-stage">
<ng-content></ng-content>
</div>
carousel-item.component.html:
<ng-content></ng-content>
I think the only solution is to go with @ContentChildren()
In my carousel.component.ts
:
import { ContentChildren, ... } from '@angular/core';
// ...
export class CarouselComponent implements AfterContentInit {
@ContentChildren(ItemComponent) carouselItems;
ngAfterContentInit() {
this.carouselItems.forEach((item: ItemComponent, currentIndex) => {
// Do stuff with each item
// Even call item's methods:
item.setWidth(someComputedWidth);
item.setClass(someClass);
}
}
}
Then, in carousel-item.component.ts
:
export class ItemComponent implements OnInit, OnDestroy {
@HostBinding('style.width') itemWidth;
@HostBinding('class') itemClass;
@HostBinding('@fade') fadeAnimationState;
setWidth(width) {
this.itemWidth = width + 'px';
}
setClass(class) {
this.itemClass = class;
}
setAnimationState(state) {
this.fadeAnimationState = state;
}
}
Apparently, I can even bind animation triggers with @HostBinding. I assumed @HostBingind() was designed to only work with the standard html attributes (style, class etc.), but it seems that I can actually bind anything (literally anything).
Does anybody have a better solution? Before I accept my own answer...