Issue
I'd like to figure out how to code up the following scenario:
app.component.html:
<div *appSlideOutDir>Hey there!</div>
The directive code is this:
export class SlideOutDirDirective implements OnInit {
constructor(
private viewContainer: ViewContainerRef,
private templateRef: TemplateRef<any>
) {}
ngOnInit() {
const slideOutComponent =
this.viewContainer.createComponent<SlideInComponent>(SlideInComponent);
slideOutComponent.instance.viewContainer.clear();
slideOutComponent.instance.viewContainer.createEmbeddedView(
this.templateRef
);
}
}
The SlideOutComponent code is this:
export class SlideInComponent {
constructor(public viewContainer: ViewContainerRef) {}
Its template is this:
<div [class.slide-in]="show">
<ng-content></ng-content>
</div>
This SlideOutComponent was originally used as a component you can wrap around anything and make it a slide-out snackbar (like in material) type of thing. However, I wanted to reuse it and use it in a directive to achieve the same thing...
However, the current code does NOT inject the original contents of Hey there!
INSIDE the SlideOutComponent, but next to it as a sibling:
<app-slide-in>...</app-slide-in>
<div>Hey there!</div>
How do I get the Hey there!
body of the original tag with the directive appear INSIDE the <app-slide-in>
?
Solution
After some research on this, I have the answer for you.
Change your SlideOutComponent
to accept a templateRef
as input.
@Input() controlTemplate: TemplateRef<any>;
Then, in HTML, change ng-content
to this:
<ng-container *ngTemplateOutlet="controlTemplate">
</ng-container>
Finally, change:
slideOutComponent.instance.viewContainer.createEmbeddedView(
this.templateRef
);
to:
slideOutComponent.instance.controlTemplate = this.templateRef;
This approach worked for me - I was able to wrap any component with a label.
Answered By - Victor Zakharov
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.