Using ng-content with *ngtemplateOutlet not show in DOM - html

I have three Angular component, one base component and two child component (child1 and child2), with these structure:
child1.component.html
<ng-template #child1Template>
<div>
<h1>CHILD 1</h1>
</div>
</ng-template>
child2.component.html
<ng-template #child2Template>
<div>
<h1>CHILD 2</h1>
</div>
</ng-template>
base.component.html
<app-child1 #wrapper_child1 class="hidden"></app-child1>
<app-child2 #wrapper_child2 class="hidden"></app-child2>
<div class="baseContainer">
<ng-content *ngTemplateOutlet="wrapper_child1.child1Template"></ng-content>
<ng-content *ngTemplateOutlet="wrapper_child2.child1Template"></ng-content>
</div>
When I inspect the DOM, it shows child1 correctly but child2 not appears and there is that
<!--bindings={
"ng-reflect-ng-template-outlet": "[object Object]"
}-->
Anyone has some explenation?
Please note that my structure absolutely needs this structure because I need to insert the content of childs in the base component WITHOUT adding additional html tags.
Thanks!

Thanks to Vovan_Super I solved my issue adding this line of code in childs component
#ViewChild('child1Template') child1Template: TemplateRef<any>;

Related

Angular, ng-templates with if condition

I want to call for two separate templates according to role id changes. I can get my role which role as
ngIf="rolet.role.id== adminRoleId
two templates are,
<ng-template #role ></ng-template>
and
<ng-template #admin ></ng-template>
I really don't know how many role in your project. But if you want to use two ng-template,check and test with the following code.
<div *ngIf="ngIf="rolet.role.id== adminRoleId; then #role else #admin"></div>
<ng-template #role>
...
</ng-template>
<ng-template #admin>
....
</ng-template>
You can always use a switch case.
It's faster and say cleaner (personal opinion)
<div [ngSwitch]="num">
<div *ngSwitchCase="'1'">One</div>
<div *ngSwitchCase="'2'">Two</div>
<div *ngSwitchCase="'3'">Three</div>
<div *ngSwitchCase="'4'">Four</div>
<div *ngSwitchCase="'5'">Five</div>
<div *ngSwitchDefault>This is Default</div>
</div>
I put them in separate div tags like this
<div *ngIf="rolet.role.id== adminRoleId">
<ng-template #adimn></ng-template>
</div>
<div *ngIf="rolet.role.id!= adminRoleId">
<ng-template #role></ng-template>
</div>

How can I delete buttons from an ngprime component?

I'm using a picklist primeng component, ant it has buttons that I want to delete but I don't see them in my HTML and y tried searched them but I didn't find them.
This is my HTML.
I got this picklist component from http://primefaces.org/primeng/picklist
and I want to delete the first block of buttons and the last (I only need right and left arrows)
<p-pickList [source]="sourceProducts" [target]="targetProducts" sourceHeader="Listado de clases" targetHeader="Clases asignadas" dragdrop="true"
[sourceStyle]="{'height':'300px'}" [targetStyle]="{'height':'300px'}">
<ng-template let-product pTemplate="item">
<div class="product-item">
<div class="product-list-detail">
<h5 class="mb-2">{{product.name}}</h5>
<i class="pi pi-tag product-category-icon"></i>
<span class="product-category">{{product.category}}</span>
</div>
<div class="product-list-action">
<span [class]="'product-badge status-' + product.inventoryStatus.toLowerCase()">{{product.inventoryStatus}}</span>
</div>
</div>
</ng-template>
</p-pickList>
I reviewed the picklist.d.ts file but I didn't find anything
You need to add showSourceControls and showTargetControls properties.
like this :
<p-pickList [showSourceControls]="false" [showTargetControls]="false"></p-pickList>

I'm trying to distribute the content from *ngFor over different html elements, in different divs

I have a set of buttons that are created with the ngFor functionality.
Separate to these buttons there is a set of that are toggled to visible and invisible when you press these buttons.
What I am trying to achieve is that the content loaded in that second set of divs matches the content of the ngFor-created buttons.
All documentation I find online treates these problems with a table and table rows but that's always within the same Element.
the buttons
and the content
enter image description here
<div id="map" class="blue">
<!-- set of buttons filled with data from arrData:-->
<div *ngFor="let Lore of arrData" id="Content-knop" class="black knop" (click)="LoreToggle()">
{{Lore.Name}}
So what I am trying to do is load the rest of the data associated with Lore.Name on the component beneath, that is toggled to visible and invisible by the LoreToggle function in the element above.
<table>
<tr>Name <!--Load content from Content-Knop here--></tr>
<tr>Tribe <!--Load content from Content-Knop here--></tr>
<tr>Region <!--Load content from Content-Knop here--></tr>
</table>
<div class="green">
<p>Description <!--load content from Content-Knop here--></p>
</div>
I hope this makes sense. I know my code is missing some ng selected functionality somewhere but I can't find a clean, simple solution that matches my criteria,
I am still not quite certain that I fully understand your issue, but to me it sounds as simple as this:
example.component.ts:
const arrData = [
{ name: 'name1', tribe: 'tribe1', region: 'region1' },
{ name: 'name2', tribe: 'tribe2', region: 'region2' },
...
];
let visibleData;
public toggleVisibleData(data) {
this.visibleData = data;
}
example.component.html
<!-- set of buttons filled with data from arrData:-->
<div *ngFor="let lore of arrData" (click)="toggleVisibleData(lore)">
{{lore.name}}
</div>
...
<ng-container*ngIf="visibleData">
<table>
<tr>{{ visibleData.name }}</tr>
<tr>{{ visibleData.tribe }}</tr>
<tr>{{ visibleData.region }}</tr>
</table>
<div class="green">
<p>{{ visibleData.description }}</p>
</div>
</ng-container>
Please also notice that I corrected the code to stick to the Angular coding style guidelines.

Angular: check if one of the ng-content slots provided

I have component template with multiple ng-content elements:
<div class="form__general">
<ng-content select="[general]"></ng-content>
</div>
<div class="form__footer">
<ng-content select="[footer]"></ng-content>
</div>
How can I check inside *ngIf condition is #footer is provided?
I tried something like this, but this does not work:
<div *ngIf="#footer" class="form__footer">
<ng-content select="[footer]"></ng-content>
</div>
Remove # from the condition check.
Sample Code Snippet:
app.component.html
<h1 #footer>Welcome</h1>
<child-comp>
<div *ngIf="footer.innerText === 'Welcome'" class="form__footer">
Hi There
</div>
</child-comp>
child.component.html
<ng-content select=".form__footer"></ng-content>

How to show/hide in Angular2

I have a component that show/hide element by clicking a button.
This is my html
<div *ngFor="let history of histories | sortdate: '-dateModified'">
<p><b>{{ history.remarks }}</b> - <i>{{history.dateModified | date:'short'}}</i></p>
<a href="google.com"
[class.datatable-icon-right]="history.$$expanded"
[class.datatable-icon-down]="!history.$$expanded"
title="Expand/Collapse Row"
(click)="toggleExpandRow(history)"></a>
<!-- hide/show this by clicking the button above.-->
<div *ngFor="let step of history.steps; let i = index">
<b>{{i+1}}.</b> {{step}}
<span class="clear"></span>
</div>
<hr />
</div>
and my .ts
toggleExpandRow(row) {
console.log('Toggled Expand Row!', row);
//row
return false;
}
trying to search but, can't find any same sample.
On jquery, I can do this, but on Angular2, I am having hard time to figure this.
There are two options:
1- You can use the hidden directive to show or hide any element
<div [hidden]="!edited" class="alert alert-success box-msg" role="alert">
<strong>List Saved!</strong> Your changes has been saved.
</div>
2- You can use the ngIf control directive to add or remove the element. This is different of the hidden directive because it does not show / hide the element, but it add / remove from the DOM. You can loose unsaved data of the element. It can be the better choice for an edit component that is cancelled.
<div *ngIf="edited" class="alert alert-success box-msg" role="alert">
<strong>List Saved!</strong> Your changes has been saved.
</div>
Use the ngIf in your repeated rows. Create a boolean property called showStep to indicate whether the row should be expanded or not.
<div *ngFor="let step of history.steps; let i = index" ngIf="history.showStep">
<b>{{i+1}}.</b> {{step}}
<span class="clear"></span>
</div>
Then, in your .ts file:
toggleExpandRow(history) {
history.showStep = !history.showStep
//note the same porperty of showStep that is used in your html
}
Extra:
In fact, to save a few lines of codes, you don't even need the toggleExpandRow function at all. You can do it inline in your html:
//other attributes omitted for brevity
<a (click)="history.showStep = !history.showStep">