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

为君一笑 提交于 2019-11-29 12:03:35

问题


I'm pretty new building directives with Angular2. What I want is to create a popup directive that will wrap the content with some css classes.

Content

Content can be pure text and headers like:

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

Then I want to give this a directive attribute like: 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, lets 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 i described so far, is this a attribute or structural directives.

import { Directive, ElementRef, HostListener, Input } from '@angular/core';

@Directive({
  selector: `[popup]`
})

export class PopupDirective {


}

回答1:


The other answer is related but different.

For something closer, see this: How to conditionally wrap a div around ng-content - my solution is for Angular 4, but the linked question has some hints about how this might be doable for Angular 2.

I solved this problem with a component and a directive combined. 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 like 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 an entryComponent inside your module :

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

so the HTML in the end is:

<some_tag *myWrapperDirective />

Which renders as:

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



回答2:


You can achieve this with a 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 {

}


来源:https://stackoverflow.com/questions/41165448/building-a-wrapper-directive-wrap-some-content-component-in-angular2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!