Reputation: 284
I'm trying to build a re-sizable panels system with Angular. So you can have multiple containers separated with a bar that allow the user to resize them.
For the moment I have a solution that requires the developer to write this HTML code:
<split-pane>
<container>Some content</container>
<separator></separator>
<container>Another content</container>
<separator></separtor>
<container>Content ?</container>
<split-pane>
split-pane, container and separator are all custom angular2 components. split-pane template is just
<ng-content></ng-content>
and I access container and separtor within split-pane using @ContentChildren(ContainerComponent)
and @ContentChildren(SeparatorComponent)
The problem I have with this solution, is that the developper needs to manually add each separator between all containers.
I'd like to have a solution where the needed HTML would be :
<split-pane>
<container>Some content</container>
<container>Another content</container>
<container>Content ?</container>
<split-pane>
And the separator components would be automatically added. But I don't know how to do this with Angular. Transclusion seems to be a way to approach this but I can't wrap my head around it.
Any idea ?
Thanks
Upvotes: 4
Views: 433
Reputation: 4031
This doesn't match your desired syntax, but by using ngFor
you may be able to make the code shorter.
Combine ngFor
with last
:
<template ngFor let-item [ngForOf]="items" let-i="index" let-last="last">
<container>{{item.content}}</container>
<separator *ngIf="!last"></separator>
</template>
Define items
in the component class, so it can obtain the data.
Upvotes: 1
Reputation: 214017
If we need to load something dynamically therefore first of all we need to say angular compiler about our dynamic component like this:
...
entryComponents: [SeparatorComponent]
})
export class AppModule {}
So our desired template looks like this:
<split-pane>
<container>Some content</container>
<container>Another content</container>
<container>Content ?</container>
</split-pane>
In order to add something between container
elements we should get ViewContainerRef
for each of container
. I would do it within SplitPaneComponent
the following way
@ContentChildren(ContainerComponent, { read: ViewContainerRef }) containersRefs: QueryList<ViewContainerRef>;
Then just use ComponentFactoryResolver
to get component factory and received above ViewContainers to add SeparatorComponent
after container
tag. Seems it should look like:
ngAfterContentInit() {
this.containersRefs.forEach((vcRef: ViewContainerRef, index: number, arr: any[]) => {
if(index === arr.length - 1) {
return;
}
let compFactory = this.resolver.resolveComponentFactory(SeparatorComponent);
let compRef = vcRef.createComponent(compFactory);
this.separators.push(compRef);
})
}
Upvotes: 3