I have this Htlm file, the first part ng-container work well and display correctly the data, but when click on the button and open the details panel, the panel use the ng-template so are not rendered correctly with the data of cycle for...I see always only the first data of the array. I think that we have to generaty dinamically the template, but I don't know... how can solve this problem?
<ng-container *ngFor="let member of members; trackBy: trackByFn;">
<div >
<div >
<!-- Info details panel button -->
<ng-container *ngIf="members?.length">
<button
[disabled]="member.session.length === 0"
mat-icon-button
(click)="openInfoDetailsPanel()"
#infoDetailsPanelOrigin>
<mat-icon
[ngClass]="{
'text-gray-400 icon-size-8': member.session.length === 0,
'text-green-600 icon-size-8': member.session.length > 0
}"
[svgIcon]="'cast_connected'">
</mat-icon>
</button>
</ng-container>
<!-- Info details panel -->
<ng-template #infoDetailsPanel>
<div >
<div >
<span>{{member | json}}</span>
<span>{{member.session | json}}</span>
<ng-container *ngFor="let item of member.session">
<tr>
<td >{{item.ip}}</td>
<td >{{convertDateTimeToLocaleDate(item.registrationDate)}}</td>
<td >{{convertDateTimeToLocaleTime(item.registrationDate)}}</td>
</tr>
</ng-container>
</div>
</div>
</ng-template>
</div>
</div>
</ng-container>
In the file TS I have this function:
@ViewChild('infoDetailsPanelOrigin') private _infoDetailsPanelOrigin: MatButton;
@ViewChild('infoDetailsPanel') private _infoDetailsPanel: TemplateRef<any>;
and the function are:
openInfoDetailsPanel(): void
{
// Create the overlay
this._overlayRef = this._overlay.create({
backdropClass : '',
hasBackdrop : true,
scrollStrategy : this._overlay.scrollStrategies.block(),
positionStrategy: this._overlay.position()
.flexibleConnectedTo(this._infoDetailsPanelOrigin._elementRef.nativeElement)
.withFlexibleDimensions(true)
.withViewportMargin(16)
.withLockedPosition(true)
.withPositions([
{
originX : 'start',
originY : 'bottom',
overlayX: 'start',
overlayY: 'top'
},
{
originX : 'start',
originY : 'top',
overlayX: 'start',
overlayY: 'bottom'
},
{
originX : 'end',
originY : 'bottom',
overlayX: 'end',
overlayY: 'top'
},
{
originX : 'end',
originY : 'top',
overlayX: 'end',
overlayY: 'bottom'
}
])
});
// Create a portal from the template
const templatePortal = new TemplatePortal(this._infoDetailsPanel, this._viewContainerRef);
// Attach the portal to the overlay
this._overlayRef.attach(templatePortal);
// Subscribe to the backdrop click
this._overlayRef.backdropClick().subscribe(() => {
// If overlay exists and attached...
if ( this._overlayRef && this._overlayRef.hasAttached() )
{
// Detach it
this._overlayRef.detach();
}
// If template portal exists and attached...
if ( templatePortal && templatePortal.isAttached )
{
// Detach it
templatePortal.detach();
}
});
}
CodePudding user response:
When create the templatePortal, the variables in your .ts are accesibles
But futhermore you can pass data, like this SO
const data={prop1:'',prop2:''}
const templatePortal = new TemplatePortal(
this._infoDetailsPanel,
this._viewContainerRef,
{
$implicit: data
});
If in your template you use
<ng-template #infoDetailsPanel let-data>
You can use
{{data.prop1}} {{data.prop2}}
</ng-template>