Angular | How to place ng-content/child content out of component using ng-template or any












0














I have a tabbing component, defined in this
https://stackblitz.com/edit/angular-tabs-example



I'm trying to put ng-content from my-tabs to external ng-template, is there any way to do that ? can i assign ng-content to TemplateRef or ViewContainerRef.










share|improve this question



























    0














    I have a tabbing component, defined in this
    https://stackblitz.com/edit/angular-tabs-example



    I'm trying to put ng-content from my-tabs to external ng-template, is there any way to do that ? can i assign ng-content to TemplateRef or ViewContainerRef.










    share|improve this question

























      0












      0








      0







      I have a tabbing component, defined in this
      https://stackblitz.com/edit/angular-tabs-example



      I'm trying to put ng-content from my-tabs to external ng-template, is there any way to do that ? can i assign ng-content to TemplateRef or ViewContainerRef.










      share|improve this question













      I have a tabbing component, defined in this
      https://stackblitz.com/edit/angular-tabs-example



      I'm trying to put ng-content from my-tabs to external ng-template, is there any way to do that ? can i assign ng-content to TemplateRef or ViewContainerRef.







      angular angular2-template






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 7 '18 at 12:30









      Zain Niazi

      199115




      199115
























          2 Answers
          2






          active

          oldest

          votes


















          0














          Yeah you can use @ContentChild form angular this will help you to pass the content from parent component to child - i will change your code a bit



          tabs.component.ts



          @Component({
          selector: 'my-tabs',
          template: `
          <ul class="nav nav-tabs">
          <li *ngFor="let tab of tabs" (click)="selectTab(tab)" [class.active]="tab.active">
          <a href="#">{{tab.title}}</a>
          </li>
          </ul>
          <ng-template [ngTemplateOutlet]="parentList"></ng-template>
          `,
          styles: [
          `
          .tab-close {
          color: gray;
          text-align: right;
          cursor: pointer;
          }
          `
          ]
          })
          export class TabsComponent implements AfterContentInit {

          @ContentChild('list') parentList: TemplateRef<any>;

          }


          app.component.ts



          @Component({
          selector: 'my-app',
          template: `
          <my-tabs>
          <my-tab [tabTitle]="'Tab 1'">
          Tab 1 content
          </my-tab>
          <ng-template #list>
          <my-tab tabTitle="Tab 2">
          Tab 2 content
          </my-tab>
          </ng-template>
          </my-tabs>
          `
          })
          export class AppComponent {
          }


          The <ng-template #list> in the parent component will pass it's content inside the template to the child component - whereas the child component will read the content and place the content in the <ng-template [ngTemplateOutlet]="parentList"></ng-template>



          By this method you can pass as many content from parent to child - hope this helps you



          Thanks - Happy coding !! - Check this link for further clarification https://angular.io/api/core/ContentChild






          share|improve this answer





















          • Thanks for help, but what i want to do is getting these rendered components out of my-tabs component and placing it anywhere in parent using templateref or anything like it. what you are doing is passing template from parent to child and placing it in child.
            – Zain Niazi
            Nov 8 '18 at 7:43










          • yeah - you can read the template of the child component by @ViewChild('templateName') templatePropName : TemplateRef<any>; and to read this template from the parent you need to read the entire child component like this @ViewChild(ChildComponentName) childPropName : ChildComponentName - this will act as instance to the child component where you can read the template this.childPropName.templatePropName so you will get your template and you can place it anywhere in your parent - Ref [angular.io/guide/…
            – Rahul
            Nov 8 '18 at 7:52










          • Reference - [angular.io/guide/…
            – Rahul
            Nov 8 '18 at 7:58












          • I have placed my solution. If you can suggest any improvements, those will be much appreciated.
            – Zain Niazi
            Nov 19 '18 at 12:06



















          0














          I solved it using code below, i'm using Output EventEmitter to get ng-content and placing it in a template in parent. Any suggestions are welcome, i need help to improve it.



          parent.component.html



          <sb-tabs contentMode="external" (templateAfterInit)="tabContentSet($event)">
          <sb-tab *ngIf="jobId" tabTitle="Invoices">
          Hello
          </sb-tab>
          </sb-tabs>


          Sidebar



          Content To Show




          parent.component.ts



          @ViewChild("tabContent")
          tabContent: TemplateRef<any>;
          tabContentSet(event) {
          this.tabContent = event.template;
          }


          tabs.component.ts



          import {
          Component, AfterContentInit, ContentChildren, QueryList
          , Input, Output, ViewChild, EventEmitter
          } from '@angular/core';

          import { TabComponent } from './tab.component'

          enum TabContentMode { internal = 'internal', external = 'external' }

          @Component({
          selector: 'sb-tabs',
          template: `
          <ul class="nav nav-tabs {{cssClasses.tabsBar}}">
          <li class="nav-item" *ngFor="let tab of tabs" (click)="selectTab(tab)">
          <a class="nav-link" [class.active]="tab.active">{{tab.title}}</a>
          </li>
          </ul>
          <ng-container *ngIf="contentMode == 'internal'" [ngTemplateOutlet]="tabsContent">
          </ng-container>
          <ng-template #tabsContent>
          <ng-content></ng-content>
          </ng-template>
          `
          })
          export class TabsComponent implements AfterContentInit {

          @Input() cssClasses: any = {
          tabsBar: 'nav nav-tabs'
          };

          @ContentChildren(TabComponent) tabs: QueryList<TabComponent>;

          @ViewChild("tabsContent")
          private externalTemplate: any;

          @Input() contentMode: TabContentMode = TabContentMode.internal;

          @Output("templateAfterInit")
          templateAfterInit = new EventEmitter();

          constructor() { }

          ngAfterContentInit(): void {

          this.templateAfterInit.emit({ template: this.externalTemplate });

          // get all active tabs
          let activeTabs = this.tabs.filter((tab) => tab.active);

          // if there is no active tab set, activate the first
          if (activeTabs.length === 0) {
          this.selectTab(this.tabs.first);
          }
          }

          selectTab(tab: TabComponent) {
          // deactivate all tabs
          this.tabs.toArray().forEach(tab => tab.active = false);

          // activate the tab the user has clicked on.
          tab.active = true;
          }

          }


          tab.component.ts



          import { Component, OnInit, Input } from '@angular/core';
          import { fadeInOut } from '@shared/common/animations';

          @Component({
          selector: 'sb-tab',
          animations: [fadeInOut],
          template: `
          <div [@fadeInOut] *ngIf="active" class="pane">
          <ng-content></ng-content>
          </div>
          `
          })
          export class TabComponent implements OnInit {

          @Input('tabTitle') title: string;
          @Input() active = false;


          constructor() { }

          ngOnInit() {
          }

          }





          share|improve this answer





















            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53189526%2fangular-how-to-place-ng-content-child-content-out-of-component-using-ng-templa%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            Yeah you can use @ContentChild form angular this will help you to pass the content from parent component to child - i will change your code a bit



            tabs.component.ts



            @Component({
            selector: 'my-tabs',
            template: `
            <ul class="nav nav-tabs">
            <li *ngFor="let tab of tabs" (click)="selectTab(tab)" [class.active]="tab.active">
            <a href="#">{{tab.title}}</a>
            </li>
            </ul>
            <ng-template [ngTemplateOutlet]="parentList"></ng-template>
            `,
            styles: [
            `
            .tab-close {
            color: gray;
            text-align: right;
            cursor: pointer;
            }
            `
            ]
            })
            export class TabsComponent implements AfterContentInit {

            @ContentChild('list') parentList: TemplateRef<any>;

            }


            app.component.ts



            @Component({
            selector: 'my-app',
            template: `
            <my-tabs>
            <my-tab [tabTitle]="'Tab 1'">
            Tab 1 content
            </my-tab>
            <ng-template #list>
            <my-tab tabTitle="Tab 2">
            Tab 2 content
            </my-tab>
            </ng-template>
            </my-tabs>
            `
            })
            export class AppComponent {
            }


            The <ng-template #list> in the parent component will pass it's content inside the template to the child component - whereas the child component will read the content and place the content in the <ng-template [ngTemplateOutlet]="parentList"></ng-template>



            By this method you can pass as many content from parent to child - hope this helps you



            Thanks - Happy coding !! - Check this link for further clarification https://angular.io/api/core/ContentChild






            share|improve this answer





















            • Thanks for help, but what i want to do is getting these rendered components out of my-tabs component and placing it anywhere in parent using templateref or anything like it. what you are doing is passing template from parent to child and placing it in child.
              – Zain Niazi
              Nov 8 '18 at 7:43










            • yeah - you can read the template of the child component by @ViewChild('templateName') templatePropName : TemplateRef<any>; and to read this template from the parent you need to read the entire child component like this @ViewChild(ChildComponentName) childPropName : ChildComponentName - this will act as instance to the child component where you can read the template this.childPropName.templatePropName so you will get your template and you can place it anywhere in your parent - Ref [angular.io/guide/…
              – Rahul
              Nov 8 '18 at 7:52










            • Reference - [angular.io/guide/…
              – Rahul
              Nov 8 '18 at 7:58












            • I have placed my solution. If you can suggest any improvements, those will be much appreciated.
              – Zain Niazi
              Nov 19 '18 at 12:06
















            0














            Yeah you can use @ContentChild form angular this will help you to pass the content from parent component to child - i will change your code a bit



            tabs.component.ts



            @Component({
            selector: 'my-tabs',
            template: `
            <ul class="nav nav-tabs">
            <li *ngFor="let tab of tabs" (click)="selectTab(tab)" [class.active]="tab.active">
            <a href="#">{{tab.title}}</a>
            </li>
            </ul>
            <ng-template [ngTemplateOutlet]="parentList"></ng-template>
            `,
            styles: [
            `
            .tab-close {
            color: gray;
            text-align: right;
            cursor: pointer;
            }
            `
            ]
            })
            export class TabsComponent implements AfterContentInit {

            @ContentChild('list') parentList: TemplateRef<any>;

            }


            app.component.ts



            @Component({
            selector: 'my-app',
            template: `
            <my-tabs>
            <my-tab [tabTitle]="'Tab 1'">
            Tab 1 content
            </my-tab>
            <ng-template #list>
            <my-tab tabTitle="Tab 2">
            Tab 2 content
            </my-tab>
            </ng-template>
            </my-tabs>
            `
            })
            export class AppComponent {
            }


            The <ng-template #list> in the parent component will pass it's content inside the template to the child component - whereas the child component will read the content and place the content in the <ng-template [ngTemplateOutlet]="parentList"></ng-template>



            By this method you can pass as many content from parent to child - hope this helps you



            Thanks - Happy coding !! - Check this link for further clarification https://angular.io/api/core/ContentChild






            share|improve this answer





















            • Thanks for help, but what i want to do is getting these rendered components out of my-tabs component and placing it anywhere in parent using templateref or anything like it. what you are doing is passing template from parent to child and placing it in child.
              – Zain Niazi
              Nov 8 '18 at 7:43










            • yeah - you can read the template of the child component by @ViewChild('templateName') templatePropName : TemplateRef<any>; and to read this template from the parent you need to read the entire child component like this @ViewChild(ChildComponentName) childPropName : ChildComponentName - this will act as instance to the child component where you can read the template this.childPropName.templatePropName so you will get your template and you can place it anywhere in your parent - Ref [angular.io/guide/…
              – Rahul
              Nov 8 '18 at 7:52










            • Reference - [angular.io/guide/…
              – Rahul
              Nov 8 '18 at 7:58












            • I have placed my solution. If you can suggest any improvements, those will be much appreciated.
              – Zain Niazi
              Nov 19 '18 at 12:06














            0












            0








            0






            Yeah you can use @ContentChild form angular this will help you to pass the content from parent component to child - i will change your code a bit



            tabs.component.ts



            @Component({
            selector: 'my-tabs',
            template: `
            <ul class="nav nav-tabs">
            <li *ngFor="let tab of tabs" (click)="selectTab(tab)" [class.active]="tab.active">
            <a href="#">{{tab.title}}</a>
            </li>
            </ul>
            <ng-template [ngTemplateOutlet]="parentList"></ng-template>
            `,
            styles: [
            `
            .tab-close {
            color: gray;
            text-align: right;
            cursor: pointer;
            }
            `
            ]
            })
            export class TabsComponent implements AfterContentInit {

            @ContentChild('list') parentList: TemplateRef<any>;

            }


            app.component.ts



            @Component({
            selector: 'my-app',
            template: `
            <my-tabs>
            <my-tab [tabTitle]="'Tab 1'">
            Tab 1 content
            </my-tab>
            <ng-template #list>
            <my-tab tabTitle="Tab 2">
            Tab 2 content
            </my-tab>
            </ng-template>
            </my-tabs>
            `
            })
            export class AppComponent {
            }


            The <ng-template #list> in the parent component will pass it's content inside the template to the child component - whereas the child component will read the content and place the content in the <ng-template [ngTemplateOutlet]="parentList"></ng-template>



            By this method you can pass as many content from parent to child - hope this helps you



            Thanks - Happy coding !! - Check this link for further clarification https://angular.io/api/core/ContentChild






            share|improve this answer












            Yeah you can use @ContentChild form angular this will help you to pass the content from parent component to child - i will change your code a bit



            tabs.component.ts



            @Component({
            selector: 'my-tabs',
            template: `
            <ul class="nav nav-tabs">
            <li *ngFor="let tab of tabs" (click)="selectTab(tab)" [class.active]="tab.active">
            <a href="#">{{tab.title}}</a>
            </li>
            </ul>
            <ng-template [ngTemplateOutlet]="parentList"></ng-template>
            `,
            styles: [
            `
            .tab-close {
            color: gray;
            text-align: right;
            cursor: pointer;
            }
            `
            ]
            })
            export class TabsComponent implements AfterContentInit {

            @ContentChild('list') parentList: TemplateRef<any>;

            }


            app.component.ts



            @Component({
            selector: 'my-app',
            template: `
            <my-tabs>
            <my-tab [tabTitle]="'Tab 1'">
            Tab 1 content
            </my-tab>
            <ng-template #list>
            <my-tab tabTitle="Tab 2">
            Tab 2 content
            </my-tab>
            </ng-template>
            </my-tabs>
            `
            })
            export class AppComponent {
            }


            The <ng-template #list> in the parent component will pass it's content inside the template to the child component - whereas the child component will read the content and place the content in the <ng-template [ngTemplateOutlet]="parentList"></ng-template>



            By this method you can pass as many content from parent to child - hope this helps you



            Thanks - Happy coding !! - Check this link for further clarification https://angular.io/api/core/ContentChild







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 7 '18 at 12:50









            Rahul

            1,0131315




            1,0131315












            • Thanks for help, but what i want to do is getting these rendered components out of my-tabs component and placing it anywhere in parent using templateref or anything like it. what you are doing is passing template from parent to child and placing it in child.
              – Zain Niazi
              Nov 8 '18 at 7:43










            • yeah - you can read the template of the child component by @ViewChild('templateName') templatePropName : TemplateRef<any>; and to read this template from the parent you need to read the entire child component like this @ViewChild(ChildComponentName) childPropName : ChildComponentName - this will act as instance to the child component where you can read the template this.childPropName.templatePropName so you will get your template and you can place it anywhere in your parent - Ref [angular.io/guide/…
              – Rahul
              Nov 8 '18 at 7:52










            • Reference - [angular.io/guide/…
              – Rahul
              Nov 8 '18 at 7:58












            • I have placed my solution. If you can suggest any improvements, those will be much appreciated.
              – Zain Niazi
              Nov 19 '18 at 12:06


















            • Thanks for help, but what i want to do is getting these rendered components out of my-tabs component and placing it anywhere in parent using templateref or anything like it. what you are doing is passing template from parent to child and placing it in child.
              – Zain Niazi
              Nov 8 '18 at 7:43










            • yeah - you can read the template of the child component by @ViewChild('templateName') templatePropName : TemplateRef<any>; and to read this template from the parent you need to read the entire child component like this @ViewChild(ChildComponentName) childPropName : ChildComponentName - this will act as instance to the child component where you can read the template this.childPropName.templatePropName so you will get your template and you can place it anywhere in your parent - Ref [angular.io/guide/…
              – Rahul
              Nov 8 '18 at 7:52










            • Reference - [angular.io/guide/…
              – Rahul
              Nov 8 '18 at 7:58












            • I have placed my solution. If you can suggest any improvements, those will be much appreciated.
              – Zain Niazi
              Nov 19 '18 at 12:06
















            Thanks for help, but what i want to do is getting these rendered components out of my-tabs component and placing it anywhere in parent using templateref or anything like it. what you are doing is passing template from parent to child and placing it in child.
            – Zain Niazi
            Nov 8 '18 at 7:43




            Thanks for help, but what i want to do is getting these rendered components out of my-tabs component and placing it anywhere in parent using templateref or anything like it. what you are doing is passing template from parent to child and placing it in child.
            – Zain Niazi
            Nov 8 '18 at 7:43












            yeah - you can read the template of the child component by @ViewChild('templateName') templatePropName : TemplateRef<any>; and to read this template from the parent you need to read the entire child component like this @ViewChild(ChildComponentName) childPropName : ChildComponentName - this will act as instance to the child component where you can read the template this.childPropName.templatePropName so you will get your template and you can place it anywhere in your parent - Ref [angular.io/guide/…
            – Rahul
            Nov 8 '18 at 7:52




            yeah - you can read the template of the child component by @ViewChild('templateName') templatePropName : TemplateRef<any>; and to read this template from the parent you need to read the entire child component like this @ViewChild(ChildComponentName) childPropName : ChildComponentName - this will act as instance to the child component where you can read the template this.childPropName.templatePropName so you will get your template and you can place it anywhere in your parent - Ref [angular.io/guide/…
            – Rahul
            Nov 8 '18 at 7:52












            Reference - [angular.io/guide/…
            – Rahul
            Nov 8 '18 at 7:58






            Reference - [angular.io/guide/…
            – Rahul
            Nov 8 '18 at 7:58














            I have placed my solution. If you can suggest any improvements, those will be much appreciated.
            – Zain Niazi
            Nov 19 '18 at 12:06




            I have placed my solution. If you can suggest any improvements, those will be much appreciated.
            – Zain Niazi
            Nov 19 '18 at 12:06













            0














            I solved it using code below, i'm using Output EventEmitter to get ng-content and placing it in a template in parent. Any suggestions are welcome, i need help to improve it.



            parent.component.html



            <sb-tabs contentMode="external" (templateAfterInit)="tabContentSet($event)">
            <sb-tab *ngIf="jobId" tabTitle="Invoices">
            Hello
            </sb-tab>
            </sb-tabs>


            Sidebar



            Content To Show




            parent.component.ts



            @ViewChild("tabContent")
            tabContent: TemplateRef<any>;
            tabContentSet(event) {
            this.tabContent = event.template;
            }


            tabs.component.ts



            import {
            Component, AfterContentInit, ContentChildren, QueryList
            , Input, Output, ViewChild, EventEmitter
            } from '@angular/core';

            import { TabComponent } from './tab.component'

            enum TabContentMode { internal = 'internal', external = 'external' }

            @Component({
            selector: 'sb-tabs',
            template: `
            <ul class="nav nav-tabs {{cssClasses.tabsBar}}">
            <li class="nav-item" *ngFor="let tab of tabs" (click)="selectTab(tab)">
            <a class="nav-link" [class.active]="tab.active">{{tab.title}}</a>
            </li>
            </ul>
            <ng-container *ngIf="contentMode == 'internal'" [ngTemplateOutlet]="tabsContent">
            </ng-container>
            <ng-template #tabsContent>
            <ng-content></ng-content>
            </ng-template>
            `
            })
            export class TabsComponent implements AfterContentInit {

            @Input() cssClasses: any = {
            tabsBar: 'nav nav-tabs'
            };

            @ContentChildren(TabComponent) tabs: QueryList<TabComponent>;

            @ViewChild("tabsContent")
            private externalTemplate: any;

            @Input() contentMode: TabContentMode = TabContentMode.internal;

            @Output("templateAfterInit")
            templateAfterInit = new EventEmitter();

            constructor() { }

            ngAfterContentInit(): void {

            this.templateAfterInit.emit({ template: this.externalTemplate });

            // get all active tabs
            let activeTabs = this.tabs.filter((tab) => tab.active);

            // if there is no active tab set, activate the first
            if (activeTabs.length === 0) {
            this.selectTab(this.tabs.first);
            }
            }

            selectTab(tab: TabComponent) {
            // deactivate all tabs
            this.tabs.toArray().forEach(tab => tab.active = false);

            // activate the tab the user has clicked on.
            tab.active = true;
            }

            }


            tab.component.ts



            import { Component, OnInit, Input } from '@angular/core';
            import { fadeInOut } from '@shared/common/animations';

            @Component({
            selector: 'sb-tab',
            animations: [fadeInOut],
            template: `
            <div [@fadeInOut] *ngIf="active" class="pane">
            <ng-content></ng-content>
            </div>
            `
            })
            export class TabComponent implements OnInit {

            @Input('tabTitle') title: string;
            @Input() active = false;


            constructor() { }

            ngOnInit() {
            }

            }





            share|improve this answer


























              0














              I solved it using code below, i'm using Output EventEmitter to get ng-content and placing it in a template in parent. Any suggestions are welcome, i need help to improve it.



              parent.component.html



              <sb-tabs contentMode="external" (templateAfterInit)="tabContentSet($event)">
              <sb-tab *ngIf="jobId" tabTitle="Invoices">
              Hello
              </sb-tab>
              </sb-tabs>


              Sidebar



              Content To Show




              parent.component.ts



              @ViewChild("tabContent")
              tabContent: TemplateRef<any>;
              tabContentSet(event) {
              this.tabContent = event.template;
              }


              tabs.component.ts



              import {
              Component, AfterContentInit, ContentChildren, QueryList
              , Input, Output, ViewChild, EventEmitter
              } from '@angular/core';

              import { TabComponent } from './tab.component'

              enum TabContentMode { internal = 'internal', external = 'external' }

              @Component({
              selector: 'sb-tabs',
              template: `
              <ul class="nav nav-tabs {{cssClasses.tabsBar}}">
              <li class="nav-item" *ngFor="let tab of tabs" (click)="selectTab(tab)">
              <a class="nav-link" [class.active]="tab.active">{{tab.title}}</a>
              </li>
              </ul>
              <ng-container *ngIf="contentMode == 'internal'" [ngTemplateOutlet]="tabsContent">
              </ng-container>
              <ng-template #tabsContent>
              <ng-content></ng-content>
              </ng-template>
              `
              })
              export class TabsComponent implements AfterContentInit {

              @Input() cssClasses: any = {
              tabsBar: 'nav nav-tabs'
              };

              @ContentChildren(TabComponent) tabs: QueryList<TabComponent>;

              @ViewChild("tabsContent")
              private externalTemplate: any;

              @Input() contentMode: TabContentMode = TabContentMode.internal;

              @Output("templateAfterInit")
              templateAfterInit = new EventEmitter();

              constructor() { }

              ngAfterContentInit(): void {

              this.templateAfterInit.emit({ template: this.externalTemplate });

              // get all active tabs
              let activeTabs = this.tabs.filter((tab) => tab.active);

              // if there is no active tab set, activate the first
              if (activeTabs.length === 0) {
              this.selectTab(this.tabs.first);
              }
              }

              selectTab(tab: TabComponent) {
              // deactivate all tabs
              this.tabs.toArray().forEach(tab => tab.active = false);

              // activate the tab the user has clicked on.
              tab.active = true;
              }

              }


              tab.component.ts



              import { Component, OnInit, Input } from '@angular/core';
              import { fadeInOut } from '@shared/common/animations';

              @Component({
              selector: 'sb-tab',
              animations: [fadeInOut],
              template: `
              <div [@fadeInOut] *ngIf="active" class="pane">
              <ng-content></ng-content>
              </div>
              `
              })
              export class TabComponent implements OnInit {

              @Input('tabTitle') title: string;
              @Input() active = false;


              constructor() { }

              ngOnInit() {
              }

              }





              share|improve this answer
























                0












                0








                0






                I solved it using code below, i'm using Output EventEmitter to get ng-content and placing it in a template in parent. Any suggestions are welcome, i need help to improve it.



                parent.component.html



                <sb-tabs contentMode="external" (templateAfterInit)="tabContentSet($event)">
                <sb-tab *ngIf="jobId" tabTitle="Invoices">
                Hello
                </sb-tab>
                </sb-tabs>


                Sidebar



                Content To Show




                parent.component.ts



                @ViewChild("tabContent")
                tabContent: TemplateRef<any>;
                tabContentSet(event) {
                this.tabContent = event.template;
                }


                tabs.component.ts



                import {
                Component, AfterContentInit, ContentChildren, QueryList
                , Input, Output, ViewChild, EventEmitter
                } from '@angular/core';

                import { TabComponent } from './tab.component'

                enum TabContentMode { internal = 'internal', external = 'external' }

                @Component({
                selector: 'sb-tabs',
                template: `
                <ul class="nav nav-tabs {{cssClasses.tabsBar}}">
                <li class="nav-item" *ngFor="let tab of tabs" (click)="selectTab(tab)">
                <a class="nav-link" [class.active]="tab.active">{{tab.title}}</a>
                </li>
                </ul>
                <ng-container *ngIf="contentMode == 'internal'" [ngTemplateOutlet]="tabsContent">
                </ng-container>
                <ng-template #tabsContent>
                <ng-content></ng-content>
                </ng-template>
                `
                })
                export class TabsComponent implements AfterContentInit {

                @Input() cssClasses: any = {
                tabsBar: 'nav nav-tabs'
                };

                @ContentChildren(TabComponent) tabs: QueryList<TabComponent>;

                @ViewChild("tabsContent")
                private externalTemplate: any;

                @Input() contentMode: TabContentMode = TabContentMode.internal;

                @Output("templateAfterInit")
                templateAfterInit = new EventEmitter();

                constructor() { }

                ngAfterContentInit(): void {

                this.templateAfterInit.emit({ template: this.externalTemplate });

                // get all active tabs
                let activeTabs = this.tabs.filter((tab) => tab.active);

                // if there is no active tab set, activate the first
                if (activeTabs.length === 0) {
                this.selectTab(this.tabs.first);
                }
                }

                selectTab(tab: TabComponent) {
                // deactivate all tabs
                this.tabs.toArray().forEach(tab => tab.active = false);

                // activate the tab the user has clicked on.
                tab.active = true;
                }

                }


                tab.component.ts



                import { Component, OnInit, Input } from '@angular/core';
                import { fadeInOut } from '@shared/common/animations';

                @Component({
                selector: 'sb-tab',
                animations: [fadeInOut],
                template: `
                <div [@fadeInOut] *ngIf="active" class="pane">
                <ng-content></ng-content>
                </div>
                `
                })
                export class TabComponent implements OnInit {

                @Input('tabTitle') title: string;
                @Input() active = false;


                constructor() { }

                ngOnInit() {
                }

                }





                share|improve this answer












                I solved it using code below, i'm using Output EventEmitter to get ng-content and placing it in a template in parent. Any suggestions are welcome, i need help to improve it.



                parent.component.html



                <sb-tabs contentMode="external" (templateAfterInit)="tabContentSet($event)">
                <sb-tab *ngIf="jobId" tabTitle="Invoices">
                Hello
                </sb-tab>
                </sb-tabs>


                Sidebar



                Content To Show




                parent.component.ts



                @ViewChild("tabContent")
                tabContent: TemplateRef<any>;
                tabContentSet(event) {
                this.tabContent = event.template;
                }


                tabs.component.ts



                import {
                Component, AfterContentInit, ContentChildren, QueryList
                , Input, Output, ViewChild, EventEmitter
                } from '@angular/core';

                import { TabComponent } from './tab.component'

                enum TabContentMode { internal = 'internal', external = 'external' }

                @Component({
                selector: 'sb-tabs',
                template: `
                <ul class="nav nav-tabs {{cssClasses.tabsBar}}">
                <li class="nav-item" *ngFor="let tab of tabs" (click)="selectTab(tab)">
                <a class="nav-link" [class.active]="tab.active">{{tab.title}}</a>
                </li>
                </ul>
                <ng-container *ngIf="contentMode == 'internal'" [ngTemplateOutlet]="tabsContent">
                </ng-container>
                <ng-template #tabsContent>
                <ng-content></ng-content>
                </ng-template>
                `
                })
                export class TabsComponent implements AfterContentInit {

                @Input() cssClasses: any = {
                tabsBar: 'nav nav-tabs'
                };

                @ContentChildren(TabComponent) tabs: QueryList<TabComponent>;

                @ViewChild("tabsContent")
                private externalTemplate: any;

                @Input() contentMode: TabContentMode = TabContentMode.internal;

                @Output("templateAfterInit")
                templateAfterInit = new EventEmitter();

                constructor() { }

                ngAfterContentInit(): void {

                this.templateAfterInit.emit({ template: this.externalTemplate });

                // get all active tabs
                let activeTabs = this.tabs.filter((tab) => tab.active);

                // if there is no active tab set, activate the first
                if (activeTabs.length === 0) {
                this.selectTab(this.tabs.first);
                }
                }

                selectTab(tab: TabComponent) {
                // deactivate all tabs
                this.tabs.toArray().forEach(tab => tab.active = false);

                // activate the tab the user has clicked on.
                tab.active = true;
                }

                }


                tab.component.ts



                import { Component, OnInit, Input } from '@angular/core';
                import { fadeInOut } from '@shared/common/animations';

                @Component({
                selector: 'sb-tab',
                animations: [fadeInOut],
                template: `
                <div [@fadeInOut] *ngIf="active" class="pane">
                <ng-content></ng-content>
                </div>
                `
                })
                export class TabComponent implements OnInit {

                @Input('tabTitle') title: string;
                @Input() active = false;


                constructor() { }

                ngOnInit() {
                }

                }






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 19 '18 at 12:05









                Zain Niazi

                199115




                199115






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53189526%2fangular-how-to-place-ng-content-child-content-out-of-component-using-ng-templa%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

                    Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

                    A Topological Invariant for $pi_3(U(n))$