Angular 6+. How to extend a template adding new actions such as JSF?











up vote
0
down vote

favorite
1












I'm trying to implement the concept of pages composition from JSF in Angular6 + but I have no idea how to start it. Here is what I need:



1) A template page such as search page where there are placeholders for fields, search action and search results table.



2) A page that extends template and add its fields, action and results



3) Possibility to extend # 2 and add custom actions to results data table rows.



Following picture describes each item above:



1) Search page general template



Search page template



2) Custom search page (extends #1)



Custom Search Page without action



3) Custom action added to search page (extends #2)



Custom search



3.1) Similar page to #3 but it has different action on result row (extends #2)



Alternate custom page



I want to is to standardize all the pages based on few base templates (# 1) and reuse specific pages adding new actions to it (#2). As the result, # 3 will be shown the final user and it may be used in different places with minor changes, for instance, I can search for the employee and open it OR I can lookup employee using this same search page but instead of opening its record, I will select it to fill a field from other form. In this example, all I need to do is the extend #2 and add specific action that will open or just lookup employee and set to other form.



PS: Developer may add component in placeholders.



Updates:



22/11/2018



Based on advice from Bunyamin Coskuner, I implemented a sample pretty quickly but now I'm stuck on a specific behavior.



I created a StackBlitz project and published my sample code:



https://stackblitz.com/edit/angular-s2wkpw



Just click on "search" and take a look at the results. Action buttons are added only in last row. What is the best way to replicate these buttons in every row?



PS: Each button must pass correct parameter based on what is in the row to controller.



I would like to ask the Angular experts if is this the best approach to archieve what I'm trying to.





Thanks in advance.










share|improve this question
























  • This is totally doable, but to answer it will take some time which is I don't have right now. I would suggest you to read about angular content projection and try to come up with a solution. If you try to implement it yourself and ask some questions along the way, people will more likely try to help you. At this moment, you haven't provided any code that you've written.
    – Bunyamin Coskuner
    Nov 19 at 13:13










  • Hello @BunyaminCoskuner! Thank you for your time, actually I'm looking for a starting point and you gave me one, I'll find more info about content projection and try to implement and share some code here.
    – Emilio Numazaki
    Nov 19 at 13:43










  • Hello @BunyaminCoskuner, added a sample code but now I'm stuck on specific issue. Could you, please, advice me what is the best way to solve it?
    – Emilio Numazaki
    2 days ago










  • Alright, I'll check it out and get back to you.
    – Bunyamin Coskuner
    2 days ago










  • Posted an answer
    – Bunyamin Coskuner
    2 days ago















up vote
0
down vote

favorite
1












I'm trying to implement the concept of pages composition from JSF in Angular6 + but I have no idea how to start it. Here is what I need:



1) A template page such as search page where there are placeholders for fields, search action and search results table.



2) A page that extends template and add its fields, action and results



3) Possibility to extend # 2 and add custom actions to results data table rows.



Following picture describes each item above:



1) Search page general template



Search page template



2) Custom search page (extends #1)



Custom Search Page without action



3) Custom action added to search page (extends #2)



Custom search



3.1) Similar page to #3 but it has different action on result row (extends #2)



Alternate custom page



I want to is to standardize all the pages based on few base templates (# 1) and reuse specific pages adding new actions to it (#2). As the result, # 3 will be shown the final user and it may be used in different places with minor changes, for instance, I can search for the employee and open it OR I can lookup employee using this same search page but instead of opening its record, I will select it to fill a field from other form. In this example, all I need to do is the extend #2 and add specific action that will open or just lookup employee and set to other form.



PS: Developer may add component in placeholders.



Updates:



22/11/2018



Based on advice from Bunyamin Coskuner, I implemented a sample pretty quickly but now I'm stuck on a specific behavior.



I created a StackBlitz project and published my sample code:



https://stackblitz.com/edit/angular-s2wkpw



Just click on "search" and take a look at the results. Action buttons are added only in last row. What is the best way to replicate these buttons in every row?



PS: Each button must pass correct parameter based on what is in the row to controller.



I would like to ask the Angular experts if is this the best approach to archieve what I'm trying to.





Thanks in advance.










share|improve this question
























  • This is totally doable, but to answer it will take some time which is I don't have right now. I would suggest you to read about angular content projection and try to come up with a solution. If you try to implement it yourself and ask some questions along the way, people will more likely try to help you. At this moment, you haven't provided any code that you've written.
    – Bunyamin Coskuner
    Nov 19 at 13:13










  • Hello @BunyaminCoskuner! Thank you for your time, actually I'm looking for a starting point and you gave me one, I'll find more info about content projection and try to implement and share some code here.
    – Emilio Numazaki
    Nov 19 at 13:43










  • Hello @BunyaminCoskuner, added a sample code but now I'm stuck on specific issue. Could you, please, advice me what is the best way to solve it?
    – Emilio Numazaki
    2 days ago










  • Alright, I'll check it out and get back to you.
    – Bunyamin Coskuner
    2 days ago










  • Posted an answer
    – Bunyamin Coskuner
    2 days ago













up vote
0
down vote

favorite
1









up vote
0
down vote

favorite
1






1





I'm trying to implement the concept of pages composition from JSF in Angular6 + but I have no idea how to start it. Here is what I need:



1) A template page such as search page where there are placeholders for fields, search action and search results table.



2) A page that extends template and add its fields, action and results



3) Possibility to extend # 2 and add custom actions to results data table rows.



Following picture describes each item above:



1) Search page general template



Search page template



2) Custom search page (extends #1)



Custom Search Page without action



3) Custom action added to search page (extends #2)



Custom search



3.1) Similar page to #3 but it has different action on result row (extends #2)



Alternate custom page



I want to is to standardize all the pages based on few base templates (# 1) and reuse specific pages adding new actions to it (#2). As the result, # 3 will be shown the final user and it may be used in different places with minor changes, for instance, I can search for the employee and open it OR I can lookup employee using this same search page but instead of opening its record, I will select it to fill a field from other form. In this example, all I need to do is the extend #2 and add specific action that will open or just lookup employee and set to other form.



PS: Developer may add component in placeholders.



Updates:



22/11/2018



Based on advice from Bunyamin Coskuner, I implemented a sample pretty quickly but now I'm stuck on a specific behavior.



I created a StackBlitz project and published my sample code:



https://stackblitz.com/edit/angular-s2wkpw



Just click on "search" and take a look at the results. Action buttons are added only in last row. What is the best way to replicate these buttons in every row?



PS: Each button must pass correct parameter based on what is in the row to controller.



I would like to ask the Angular experts if is this the best approach to archieve what I'm trying to.





Thanks in advance.










share|improve this question















I'm trying to implement the concept of pages composition from JSF in Angular6 + but I have no idea how to start it. Here is what I need:



1) A template page such as search page where there are placeholders for fields, search action and search results table.



2) A page that extends template and add its fields, action and results



3) Possibility to extend # 2 and add custom actions to results data table rows.



Following picture describes each item above:



1) Search page general template



Search page template



2) Custom search page (extends #1)



Custom Search Page without action



3) Custom action added to search page (extends #2)



Custom search



3.1) Similar page to #3 but it has different action on result row (extends #2)



Alternate custom page



I want to is to standardize all the pages based on few base templates (# 1) and reuse specific pages adding new actions to it (#2). As the result, # 3 will be shown the final user and it may be used in different places with minor changes, for instance, I can search for the employee and open it OR I can lookup employee using this same search page but instead of opening its record, I will select it to fill a field from other form. In this example, all I need to do is the extend #2 and add specific action that will open or just lookup employee and set to other form.



PS: Developer may add component in placeholders.



Updates:



22/11/2018



Based on advice from Bunyamin Coskuner, I implemented a sample pretty quickly but now I'm stuck on a specific behavior.



I created a StackBlitz project and published my sample code:



https://stackblitz.com/edit/angular-s2wkpw



Just click on "search" and take a look at the results. Action buttons are added only in last row. What is the best way to replicate these buttons in every row?



PS: Each button must pass correct parameter based on what is in the row to controller.



I would like to ask the Angular experts if is this the best approach to archieve what I'm trying to.





Thanks in advance.







angular






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 2 days ago

























asked Nov 19 at 12:54









Emilio Numazaki

346




346












  • This is totally doable, but to answer it will take some time which is I don't have right now. I would suggest you to read about angular content projection and try to come up with a solution. If you try to implement it yourself and ask some questions along the way, people will more likely try to help you. At this moment, you haven't provided any code that you've written.
    – Bunyamin Coskuner
    Nov 19 at 13:13










  • Hello @BunyaminCoskuner! Thank you for your time, actually I'm looking for a starting point and you gave me one, I'll find more info about content projection and try to implement and share some code here.
    – Emilio Numazaki
    Nov 19 at 13:43










  • Hello @BunyaminCoskuner, added a sample code but now I'm stuck on specific issue. Could you, please, advice me what is the best way to solve it?
    – Emilio Numazaki
    2 days ago










  • Alright, I'll check it out and get back to you.
    – Bunyamin Coskuner
    2 days ago










  • Posted an answer
    – Bunyamin Coskuner
    2 days ago


















  • This is totally doable, but to answer it will take some time which is I don't have right now. I would suggest you to read about angular content projection and try to come up with a solution. If you try to implement it yourself and ask some questions along the way, people will more likely try to help you. At this moment, you haven't provided any code that you've written.
    – Bunyamin Coskuner
    Nov 19 at 13:13










  • Hello @BunyaminCoskuner! Thank you for your time, actually I'm looking for a starting point and you gave me one, I'll find more info about content projection and try to implement and share some code here.
    – Emilio Numazaki
    Nov 19 at 13:43










  • Hello @BunyaminCoskuner, added a sample code but now I'm stuck on specific issue. Could you, please, advice me what is the best way to solve it?
    – Emilio Numazaki
    2 days ago










  • Alright, I'll check it out and get back to you.
    – Bunyamin Coskuner
    2 days ago










  • Posted an answer
    – Bunyamin Coskuner
    2 days ago
















This is totally doable, but to answer it will take some time which is I don't have right now. I would suggest you to read about angular content projection and try to come up with a solution. If you try to implement it yourself and ask some questions along the way, people will more likely try to help you. At this moment, you haven't provided any code that you've written.
– Bunyamin Coskuner
Nov 19 at 13:13




This is totally doable, but to answer it will take some time which is I don't have right now. I would suggest you to read about angular content projection and try to come up with a solution. If you try to implement it yourself and ask some questions along the way, people will more likely try to help you. At this moment, you haven't provided any code that you've written.
– Bunyamin Coskuner
Nov 19 at 13:13












Hello @BunyaminCoskuner! Thank you for your time, actually I'm looking for a starting point and you gave me one, I'll find more info about content projection and try to implement and share some code here.
– Emilio Numazaki
Nov 19 at 13:43




Hello @BunyaminCoskuner! Thank you for your time, actually I'm looking for a starting point and you gave me one, I'll find more info about content projection and try to implement and share some code here.
– Emilio Numazaki
Nov 19 at 13:43












Hello @BunyaminCoskuner, added a sample code but now I'm stuck on specific issue. Could you, please, advice me what is the best way to solve it?
– Emilio Numazaki
2 days ago




Hello @BunyaminCoskuner, added a sample code but now I'm stuck on specific issue. Could you, please, advice me what is the best way to solve it?
– Emilio Numazaki
2 days ago












Alright, I'll check it out and get back to you.
– Bunyamin Coskuner
2 days ago




Alright, I'll check it out and get back to you.
– Bunyamin Coskuner
2 days ago












Posted an answer
– Bunyamin Coskuner
2 days ago




Posted an answer
– Bunyamin Coskuner
2 days ago












1 Answer
1






active

oldest

votes

















up vote
0
down vote













You came pretty close, I just added a directive to solve the rest. Here is the final stackblitz



<ng-content select="...> works on static content projection. Sometimes, you need more powerful directive than that.



There is a little trick I got it from Angular Material codebase and use it in almost all of my components which is providing customizable templates.



Instead of writing <ng-content select="button"> which overrides other rows of the table and only put the buttons on the last one, you declare a directive as follows



@Directive({ selector: '[appPersonSearchButtons]' })
export class TemplatePersonSearchButtonsDirective {
constructor(public template: TemplateRef<any>) { }
}


This directive may not look like it is doing much and I assure you it is!
It has single property which is template. It is injected here because we will use this directive with ng-template only! If you use this directive on any other element than ng-template you will get an error!



You should put this directive into declarations array of your module



declarations: [ ... TemplatePersonSearchButtonsDirective ... ]


Now, it is time to change <ng-content select="button"> to something else.
First, let's make sure whether consumers of this component used this directive within their template.



I added this line to TemplatePersonSearchComponent



@ContentChild(TemplatePersonSearchButtonsDirective) buttons: TemplatePersonSearchButtonsDirective;


I've changed <tr *ngFor...> to following



<tr *ngFor="let person of persons; let i = index">
<td width="80%">{{person}}</td>
<td>
<ng-container *ngIf="buttons">
<ng-container *ngTemplateOutlet="buttons.template;
context: { $implicit: person, index: i}">
</ng-container>
</ng-container>
</td>
</tr>


ngTemplateOutlet is a directive that takes a TemplateRef as an input (which comes from buttons.template in this case). Also, you can pass a context too so that you can expose some data to the users (which will come in handy later).



Let's use it in our employee-search-component. It is pretty much the same as you wrote it, I just moved buttons inside of an ng-template as follows



<app-template-person-search>
<ng-template appPersonSearchButtons let-personObj let-id="index">
<button (click)="openPerson(personObj, id)">Open</button>
<button (click)="deletePerson(personObj, id)">Delete</button>
</ng-template>
</app-template-person-search>


Remember, we defined our context as context: { $implicit: person, index: i}"



Since, we defined person as $implicit, you can write anything starting with let- to retrieve that object. I chose personObj to show that you can type anything. Also, I retrieved index as id and pass these objects into a function.



openPerson(person, id) {
alert('Open ' + person + ' ' + id);
}

deletePerson(person, id) {
alert('Delete ' + person + ' ' + id);
}





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',
    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%2f53375104%2fangular-6-how-to-extend-a-template-adding-new-actions-such-as-jsf%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    You came pretty close, I just added a directive to solve the rest. Here is the final stackblitz



    <ng-content select="...> works on static content projection. Sometimes, you need more powerful directive than that.



    There is a little trick I got it from Angular Material codebase and use it in almost all of my components which is providing customizable templates.



    Instead of writing <ng-content select="button"> which overrides other rows of the table and only put the buttons on the last one, you declare a directive as follows



    @Directive({ selector: '[appPersonSearchButtons]' })
    export class TemplatePersonSearchButtonsDirective {
    constructor(public template: TemplateRef<any>) { }
    }


    This directive may not look like it is doing much and I assure you it is!
    It has single property which is template. It is injected here because we will use this directive with ng-template only! If you use this directive on any other element than ng-template you will get an error!



    You should put this directive into declarations array of your module



    declarations: [ ... TemplatePersonSearchButtonsDirective ... ]


    Now, it is time to change <ng-content select="button"> to something else.
    First, let's make sure whether consumers of this component used this directive within their template.



    I added this line to TemplatePersonSearchComponent



    @ContentChild(TemplatePersonSearchButtonsDirective) buttons: TemplatePersonSearchButtonsDirective;


    I've changed <tr *ngFor...> to following



    <tr *ngFor="let person of persons; let i = index">
    <td width="80%">{{person}}</td>
    <td>
    <ng-container *ngIf="buttons">
    <ng-container *ngTemplateOutlet="buttons.template;
    context: { $implicit: person, index: i}">
    </ng-container>
    </ng-container>
    </td>
    </tr>


    ngTemplateOutlet is a directive that takes a TemplateRef as an input (which comes from buttons.template in this case). Also, you can pass a context too so that you can expose some data to the users (which will come in handy later).



    Let's use it in our employee-search-component. It is pretty much the same as you wrote it, I just moved buttons inside of an ng-template as follows



    <app-template-person-search>
    <ng-template appPersonSearchButtons let-personObj let-id="index">
    <button (click)="openPerson(personObj, id)">Open</button>
    <button (click)="deletePerson(personObj, id)">Delete</button>
    </ng-template>
    </app-template-person-search>


    Remember, we defined our context as context: { $implicit: person, index: i}"



    Since, we defined person as $implicit, you can write anything starting with let- to retrieve that object. I chose personObj to show that you can type anything. Also, I retrieved index as id and pass these objects into a function.



    openPerson(person, id) {
    alert('Open ' + person + ' ' + id);
    }

    deletePerson(person, id) {
    alert('Delete ' + person + ' ' + id);
    }





    share|improve this answer



























      up vote
      0
      down vote













      You came pretty close, I just added a directive to solve the rest. Here is the final stackblitz



      <ng-content select="...> works on static content projection. Sometimes, you need more powerful directive than that.



      There is a little trick I got it from Angular Material codebase and use it in almost all of my components which is providing customizable templates.



      Instead of writing <ng-content select="button"> which overrides other rows of the table and only put the buttons on the last one, you declare a directive as follows



      @Directive({ selector: '[appPersonSearchButtons]' })
      export class TemplatePersonSearchButtonsDirective {
      constructor(public template: TemplateRef<any>) { }
      }


      This directive may not look like it is doing much and I assure you it is!
      It has single property which is template. It is injected here because we will use this directive with ng-template only! If you use this directive on any other element than ng-template you will get an error!



      You should put this directive into declarations array of your module



      declarations: [ ... TemplatePersonSearchButtonsDirective ... ]


      Now, it is time to change <ng-content select="button"> to something else.
      First, let's make sure whether consumers of this component used this directive within their template.



      I added this line to TemplatePersonSearchComponent



      @ContentChild(TemplatePersonSearchButtonsDirective) buttons: TemplatePersonSearchButtonsDirective;


      I've changed <tr *ngFor...> to following



      <tr *ngFor="let person of persons; let i = index">
      <td width="80%">{{person}}</td>
      <td>
      <ng-container *ngIf="buttons">
      <ng-container *ngTemplateOutlet="buttons.template;
      context: { $implicit: person, index: i}">
      </ng-container>
      </ng-container>
      </td>
      </tr>


      ngTemplateOutlet is a directive that takes a TemplateRef as an input (which comes from buttons.template in this case). Also, you can pass a context too so that you can expose some data to the users (which will come in handy later).



      Let's use it in our employee-search-component. It is pretty much the same as you wrote it, I just moved buttons inside of an ng-template as follows



      <app-template-person-search>
      <ng-template appPersonSearchButtons let-personObj let-id="index">
      <button (click)="openPerson(personObj, id)">Open</button>
      <button (click)="deletePerson(personObj, id)">Delete</button>
      </ng-template>
      </app-template-person-search>


      Remember, we defined our context as context: { $implicit: person, index: i}"



      Since, we defined person as $implicit, you can write anything starting with let- to retrieve that object. I chose personObj to show that you can type anything. Also, I retrieved index as id and pass these objects into a function.



      openPerson(person, id) {
      alert('Open ' + person + ' ' + id);
      }

      deletePerson(person, id) {
      alert('Delete ' + person + ' ' + id);
      }





      share|improve this answer

























        up vote
        0
        down vote










        up vote
        0
        down vote









        You came pretty close, I just added a directive to solve the rest. Here is the final stackblitz



        <ng-content select="...> works on static content projection. Sometimes, you need more powerful directive than that.



        There is a little trick I got it from Angular Material codebase and use it in almost all of my components which is providing customizable templates.



        Instead of writing <ng-content select="button"> which overrides other rows of the table and only put the buttons on the last one, you declare a directive as follows



        @Directive({ selector: '[appPersonSearchButtons]' })
        export class TemplatePersonSearchButtonsDirective {
        constructor(public template: TemplateRef<any>) { }
        }


        This directive may not look like it is doing much and I assure you it is!
        It has single property which is template. It is injected here because we will use this directive with ng-template only! If you use this directive on any other element than ng-template you will get an error!



        You should put this directive into declarations array of your module



        declarations: [ ... TemplatePersonSearchButtonsDirective ... ]


        Now, it is time to change <ng-content select="button"> to something else.
        First, let's make sure whether consumers of this component used this directive within their template.



        I added this line to TemplatePersonSearchComponent



        @ContentChild(TemplatePersonSearchButtonsDirective) buttons: TemplatePersonSearchButtonsDirective;


        I've changed <tr *ngFor...> to following



        <tr *ngFor="let person of persons; let i = index">
        <td width="80%">{{person}}</td>
        <td>
        <ng-container *ngIf="buttons">
        <ng-container *ngTemplateOutlet="buttons.template;
        context: { $implicit: person, index: i}">
        </ng-container>
        </ng-container>
        </td>
        </tr>


        ngTemplateOutlet is a directive that takes a TemplateRef as an input (which comes from buttons.template in this case). Also, you can pass a context too so that you can expose some data to the users (which will come in handy later).



        Let's use it in our employee-search-component. It is pretty much the same as you wrote it, I just moved buttons inside of an ng-template as follows



        <app-template-person-search>
        <ng-template appPersonSearchButtons let-personObj let-id="index">
        <button (click)="openPerson(personObj, id)">Open</button>
        <button (click)="deletePerson(personObj, id)">Delete</button>
        </ng-template>
        </app-template-person-search>


        Remember, we defined our context as context: { $implicit: person, index: i}"



        Since, we defined person as $implicit, you can write anything starting with let- to retrieve that object. I chose personObj to show that you can type anything. Also, I retrieved index as id and pass these objects into a function.



        openPerson(person, id) {
        alert('Open ' + person + ' ' + id);
        }

        deletePerson(person, id) {
        alert('Delete ' + person + ' ' + id);
        }





        share|improve this answer














        You came pretty close, I just added a directive to solve the rest. Here is the final stackblitz



        <ng-content select="...> works on static content projection. Sometimes, you need more powerful directive than that.



        There is a little trick I got it from Angular Material codebase and use it in almost all of my components which is providing customizable templates.



        Instead of writing <ng-content select="button"> which overrides other rows of the table and only put the buttons on the last one, you declare a directive as follows



        @Directive({ selector: '[appPersonSearchButtons]' })
        export class TemplatePersonSearchButtonsDirective {
        constructor(public template: TemplateRef<any>) { }
        }


        This directive may not look like it is doing much and I assure you it is!
        It has single property which is template. It is injected here because we will use this directive with ng-template only! If you use this directive on any other element than ng-template you will get an error!



        You should put this directive into declarations array of your module



        declarations: [ ... TemplatePersonSearchButtonsDirective ... ]


        Now, it is time to change <ng-content select="button"> to something else.
        First, let's make sure whether consumers of this component used this directive within their template.



        I added this line to TemplatePersonSearchComponent



        @ContentChild(TemplatePersonSearchButtonsDirective) buttons: TemplatePersonSearchButtonsDirective;


        I've changed <tr *ngFor...> to following



        <tr *ngFor="let person of persons; let i = index">
        <td width="80%">{{person}}</td>
        <td>
        <ng-container *ngIf="buttons">
        <ng-container *ngTemplateOutlet="buttons.template;
        context: { $implicit: person, index: i}">
        </ng-container>
        </ng-container>
        </td>
        </tr>


        ngTemplateOutlet is a directive that takes a TemplateRef as an input (which comes from buttons.template in this case). Also, you can pass a context too so that you can expose some data to the users (which will come in handy later).



        Let's use it in our employee-search-component. It is pretty much the same as you wrote it, I just moved buttons inside of an ng-template as follows



        <app-template-person-search>
        <ng-template appPersonSearchButtons let-personObj let-id="index">
        <button (click)="openPerson(personObj, id)">Open</button>
        <button (click)="deletePerson(personObj, id)">Delete</button>
        </ng-template>
        </app-template-person-search>


        Remember, we defined our context as context: { $implicit: person, index: i}"



        Since, we defined person as $implicit, you can write anything starting with let- to retrieve that object. I chose personObj to show that you can type anything. Also, I retrieved index as id and pass these objects into a function.



        openPerson(person, id) {
        alert('Open ' + person + ' ' + id);
        }

        deletePerson(person, id) {
        alert('Delete ' + person + ' ' + id);
        }






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 2 days ago

























        answered 2 days ago









        Bunyamin Coskuner

        3,1041530




        3,1041530






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53375104%2fangular-6-how-to-extend-a-template-adding-new-actions-such-as-jsf%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

            404 Error Contact Form 7 ajax form submitting

            How to know if a Active Directory user can login interactively

            TypeError: fit_transform() missing 1 required positional argument: 'X'