Building a wrapper directive (wrapping some content / component) in angular2

I am fairly new building directives with Angular2. I want to create a popup directive that will wrap content with some css classes.

Content

Content can be pure text and headings, for example:

<div class="data"> <h2>Header</h2> Content to be placed here. </div> 

Then I want to give this attribute directives, for example: popup

 <div class="data" popup> <h2>Header</h2> Content to be placed here. </div> 

What the directive should do is to wrap the div inside, say:

 <div class="some class"> <div class="some other class"> <div class="data"> <h2>Header</h2> Content to be placed here. </div> </div> </div> 

The case that I have described so far is an attribute or structural directives.

 import { Directive, ElementRef, HostListener, Input } from '@angular/core'; @Directive({ selector: `[popup]` }) export class PopupDirective { } 
+12
source share
2 answers

The other answer is related but different.

For a more detailed look, see the following: How to conditionally wrap a div around ng-content is my solution for Angular 4, but the related question has some tips on how this can be done for Angular 2.

I solved this problem with the component and the directive. My component looks something like this:

 import { Component, Input, TemplateRef } from '@angular/core'; @Component({ selector: 'my-wrapper-container', template: ' <div class="whatever"> <ng-container *ngTemplateOutlet="template"></ng-container> </div> ' }) export class WrapperContainerComponent { @Input() template: TemplateRef<any>; } 

and my directive is this:

 import { Directive, OnInit, Input, TemplateRef, ComponentRef, ComponentFactoryResolver, ViewContainerRef } from '@angular/core'; @Directive({ selector: '[myWrapperDirective]' }) export class WrapperDirective implements OnInit { private wrapperContainer: ComponentRef<WrapperContainerComponent>; constructor( private templateRef: TemplateRef<any>, private viewContainerRef: ViewContainerRef, private componentFactoryResolver: ComponentFactoryResolver ) { } ngOnInit() { const containerFactory = this.componentFactoryResolver.resolveComponentFactory(WrapperContainerComponent); this.wrapperContainer = this.viewContainerRef.createComponent(containerFactory); this.wrapperContainer.instance.template = this.templateRef; } } 

To be able to load your component dynamically, you need to list your component as entryComponent inside your module:

 @NgModule({ imports: [CommonModule], declarations: [WrapperContainerComponent, WrapperDirective], exports: [WrapperContainerComponent, WrapperDirective], entryComponents: [WrapperContainerComponent] }) export class MyModule{} 

so HTML in the end:

 <some_tag *myWrapperDirective /> 

Which is displayed as:

 <my-wrapper-container> <div class="whatever"> <some_tag /> </div> </my-wrapper-container> 
+11
source

You can achieve this with the component attribute selector and Angular 2 Content Projection <ng-content>

 @Component({ selector: 'my-app', template: ` <div class="app"> <div class="data" myWrapper> <h2>Header</h2> Content to be placed here. </div> </div> ` }) export class AppComponent {} @Component({ selector: '[myWrapper]', template: ` <div class="my-class"> <div class="my-sub-class"> <ng-content></ng-content> </div> </div> ` }) export class MyComponent { } 
+9
source

Source: https://habr.com/ru/post/1013190/


All Articles