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












0














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 '18 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 '18 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
    Nov 22 '18 at 13:27










  • Alright, I'll check it out and get back to you.
    – Bunyamin Coskuner
    Nov 22 '18 at 13:29










  • Posted an answer
    – Bunyamin Coskuner
    Nov 22 '18 at 14:14
















0














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 '18 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 '18 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
    Nov 22 '18 at 13:27










  • Alright, I'll check it out and get back to you.
    – Bunyamin Coskuner
    Nov 22 '18 at 13:29










  • Posted an answer
    – Bunyamin Coskuner
    Nov 22 '18 at 14:14














0












0








0


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 Nov 22 '18 at 13:26

























asked Nov 19 '18 at 12:54









Emilio Numazaki

416




416












  • 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 '18 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 '18 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
    Nov 22 '18 at 13:27










  • Alright, I'll check it out and get back to you.
    – Bunyamin Coskuner
    Nov 22 '18 at 13:29










  • Posted an answer
    – Bunyamin Coskuner
    Nov 22 '18 at 14:14


















  • 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 '18 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 '18 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
    Nov 22 '18 at 13:27










  • Alright, I'll check it out and get back to you.
    – Bunyamin Coskuner
    Nov 22 '18 at 13:29










  • Posted an answer
    – Bunyamin Coskuner
    Nov 22 '18 at 14:14
















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 '18 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 '18 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 '18 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 '18 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
Nov 22 '18 at 13:27




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
Nov 22 '18 at 13:27












Alright, I'll check it out and get back to you.
– Bunyamin Coskuner
Nov 22 '18 at 13:29




Alright, I'll check it out and get back to you.
– Bunyamin Coskuner
Nov 22 '18 at 13:29












Posted an answer
– Bunyamin Coskuner
Nov 22 '18 at 14:14




Posted an answer
– Bunyamin Coskuner
Nov 22 '18 at 14:14












1 Answer
1






active

oldest

votes


















1














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























  • Very good! This is exactly what I was looking for! Thank you! Now I'll move forward on my own framework and will post here case I got stuck! Have a great week!
    – Emilio Numazaki
    Dec 3 '18 at 13:49











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%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









1














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























  • Very good! This is exactly what I was looking for! Thank you! Now I'll move forward on my own framework and will post here case I got stuck! Have a great week!
    – Emilio Numazaki
    Dec 3 '18 at 13:49
















1














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























  • Very good! This is exactly what I was looking for! Thank you! Now I'll move forward on my own framework and will post here case I got stuck! Have a great week!
    – Emilio Numazaki
    Dec 3 '18 at 13:49














1












1








1






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 Nov 22 '18 at 14:22

























answered Nov 22 '18 at 14:12









Bunyamin Coskuner

3,3871633




3,3871633












  • Very good! This is exactly what I was looking for! Thank you! Now I'll move forward on my own framework and will post here case I got stuck! Have a great week!
    – Emilio Numazaki
    Dec 3 '18 at 13:49


















  • Very good! This is exactly what I was looking for! Thank you! Now I'll move forward on my own framework and will post here case I got stuck! Have a great week!
    – Emilio Numazaki
    Dec 3 '18 at 13:49
















Very good! This is exactly what I was looking for! Thank you! Now I'll move forward on my own framework and will post here case I got stuck! Have a great week!
– Emilio Numazaki
Dec 3 '18 at 13:49




Very good! This is exactly what I was looking for! Thank you! Now I'll move forward on my own framework and will post here case I got stuck! Have a great week!
– Emilio Numazaki
Dec 3 '18 at 13:49


















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%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

MongoDB - Not Authorized To Execute Command

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

Npm cannot find a required file even through it is in the searched directory