Search code examples
angulartypescriptangular-directiveangular-template

Angular: wrapper component to pass inner directives/components


I have 3 components:

(1) AppComponent: This is just a regular AppComponent, nothing special. In app.component.html I use my MyComponent:

<my-component></my-component>

(2) MyComponent: This is just a wrapper component that contains TheirComponent like this (my.component.html):

<their-component></their-component>

(3) TheirComponent: This is a third-party component (from an NPM package). It can contain directives and other components from the third-party components. For example:

<their-component>
    <their-header>Title</their-header>
    <their-footer>Title</their-footer>
</their-component>

My goal is to put all of these additional, inner directives and components (their-header and their-footer in this example) in app.component.html, and pass it through MyComponent to TheirComponent. So my app.component.html should look like this:

<my-component>
    <their-header>Title</their-header>
    <their-footer>Title</their-footer>
</my-component>

I tried to use ng-content for this. It works with simple HTML elements, I know, but not with these third-party directives. This is what I tried (my.component.html):

<their-component>
    <ng-content></ng-content>
</their-component>

It doesn't work, and there are no errors. Maybe this is a content projection problem, I'm not sure, how this is called. Any solution for this? Thanks.


Example: https://plnkr.co/edit/SgM4sbYQrZXDcrKuon2d?p=preview


Solution

  • If you really need it you can take advantage of using ngProjectAs attribute.

    In order to have all addition functionality provided by ButtonGroup(k-group-start, k-group-end classes etc) you have to pass buttons array to kendo component.

    Here's how it could look like:

    import { Component, QueryList, ContentChildren, Input, ViewChild } from '@angular/core';
    import { Button, ButtonGroup } from '@progress/kendo-angular-buttons';
    
    @Component({
      selector: 'my-component',
      template: `
        <kendo-buttongroup>
            <ng-content ngProjectAs="[kendoButton]"></ng-content>
        </kendo-buttongroup>
      `
    })
    export class MyComponent {
    
      @ViewChild(ButtonGroup) buttonGroup: ButtonGroup;
    
      @ContentChildren(Button) buttons: QueryList<Button>;
    
      ngAfterViewInit() {
        this.buttonGroup.buttons = this.buttons;
        this.buttonGroup.ngAfterContentInit();
      }
    }
    

    Plunker Example

    See also: