According to the Angular docs, there is a microsyntax that can be used with structural directives.
So I have some code that is working with the cdkConnectedOverlay directive while using the 'long hand' form:
<ng-template
cdkConnectedOverlay
[cdkConnectedOverlayOrigin]="savedSearchTrigger"
[cdkConnectedOverlayOpen]="savedSearchToggle.checked"
[cdkConnectedOverlayHasBackdrop]="true"
[cdkConnectedOverlayBackdropClass]="'transparentOverlayBackdrop'">
My overlay contents!
</ng-template>
After reading about the microsyntax, it seems I should be able to shorten my code to:
<ng-template
*cdkConnectedOverlay="origin: savedSearchTrigger; open: savedSearchToggle.checked; hasBackdrop: true; backdropClass: 'transparentOverlayBackdrop'">
My overlay contents!
</ng-template>
However, this isn't compiling. And is giving me the error Cannot read the property 'toUpperCase' of undefined
I'm wondering if the fact I'm trying to use the microsyntax on an ng-template is the culprit.
What am I doing wrong? Is there a work around?
Angular compiler expects that the microsyntax will start either with value
*cdkConnectedOverlay="cdkConnectedOverlayValue; otherProp: otherPropValue...."
or with variable:
*cdkConnectedOverlay="let x; otherProp: otherPropValue...."
Since CdkConnectedOverlay doesn't have @Input with name CdkConnectedOverlay then you cannot use syntax like:
*cdkConnectedOverlay="1;origin: savedSearchTrigger;...
To work around it you could create a directive with [cdkConnectedOverlay] selector and the same @Input property but I would go with the first solution:
<ng-container *cdkConnectedOverlay="let x;origin: savedSearchTrigger; open: opened;
hasBackdrop: true; backdropClass: 'transparentOverlayBackdrop'">
Despite the fact that it will compile you can notice that your content is not displayed. To fix it you should use <ng-container *cdkConnectedOverlay instead of <ng-template *cdkConnectedOverlay so that My overlay contents! content won't be wrapped in additional ng-template
Finally, take a look at Ng-run Example
Update
Note, that sugar (*) syntax does not support @Output therefore the event won't be fired in the following code:
<ng-container *cdkConnectedOverlay="..." (backdropClick)="opened = false">
To work around it you could pass some handler as @Input by creating additional directive like:
@Directive({
selector: '[cdkConnectedOverlayBackdropClick]'
})
export class ConnectedOverlayBackdropClick {
@Input('cdkConnectedOverlayBackdropClick') backDropHandler: Function;
@HostListener('backdropClick')
backdropClick() {
this.backDropHandler();
}
}
And then catch event in component:
component.html
<ng-container *cdkConnectedOverlay="let item; origin: savedSearchTrigger; open: opened;
hasBackdrop: true; backdropClass: 'transparentOverlayBackdrop'; backdropClick: close">
component.ts
close = () => {
this.opened = false;
}
Ng-run Example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With