-
Notifications
You must be signed in to change notification settings - Fork 6.8k
Description
Feature Description
Tracking if a portal is attached/detached within a CdkPortalOutlet
can be cumbersome, it would be a nice improvement to expose the attached portal or the attachment/detachment state as a signal.
Use Case
We create a component portal on a parent element which will get components attached by its children. In case a component is attached, I need to adapt the styling.
Lets take the following example, my expectation initially was that the class will be set correctly.
myOutlet = viewChild(CdkPortalOutlet);
<my-child [portalOutlet]="myOutlet()"/> // outlet gets passed to children which will attach components
<section [class.attached]="myOutlet().portal">
<ng-container cdkPortalOutlet></ng-container>
</section>
The issue though is that myOutlet
is only initialized once and changes to the portal
within are not tracked if there is no other event triggering change detection at the same time. So the code above can actually get out-of-sync.
The best workaround I found is to manually keep track of the attachment/detachment.
This is more complex than it should be and my example is also possibly missing cleanup code
myOutlet = viewChild(CdkPortalOutlet);
isOutletAttached = signal(false);
effect(() => {
this.myOutlet()?.attached.subscribe(() => {
this.isOutletAttached.set(true);
this.myOutlet().attachedRef?.onDestroy(() => this.isOutletAttached.set(false));
});
});
<section [class.attached]="isOutletAttached()">...</section>
Ideally one of the internal members of the CdkPortalOutlet
should expose a signal which can be used.
myOutlet = viewChild(CdkPortalOutlet);
// multiple options
<section [class.attached]="myOutlet().portal()">...</section>
<section [class.attached]="myOutlet().attachedRef()">...</section>
<section [class.attached]="myOutlet().isAttached()">...</section>