Home > Net >  Using custom directive with ngFor on the same element
Using custom directive with ngFor on the same element

Time:07-28

I am displaying a list of Angular Material Cards like this:

<mat-card *ngFor="let todo of todos">
    <mat-card-header>
        <mat-card-title>{{{todo.title}}</mat-card-title>
    <mat-card-header>
<mat-card>

It works great but now I've got a custom directive that only displays the Card if it's enabled (based on the "id" property of the Todo object). And I want to use it on the same element.

@Directive({
    selector: '[customFeature]'
})
export class CustomFeatureDirective implements OnInit {
    @Input()
    customFeature: string;

    constructor(
        private tpl: TemplateRef<any>,
        private vcr: ViewContainerRef,
        private myService: MyService
    ) {}

    ngOnInit(): void{
        const enabled = this.myService.amIEnabled(this.customFeature)
        if(enabled)
            this.vcr.createEmbeddedView(this.tpl);
    }
}

But I don't know how to read the id property of the todo so i can assign it to the CustomFeature directive. I'm trying this:

<mat-card *ngFor="let todo of todos" *customFeature="todo.id">
    <mat-card-header>
        <mat-card-title>{{{todo.title}}</mat-card-title>
    <mat-card-header>
<mat-card> 

But the error says that you can't have multiple template bindings on one element. I thought in older versions of Angular you could do something like this. Did I completely blow the syntax or what? Thanks for any helpful tips.

CodePudding user response:

Try this instead:

<ng-container *ngFor="let todo of todos">
    <mat-card  *customFeature="todo.id">
        <mat-card-header>
            <mat-card-title>{{{todo.title}}</mat-card-title>
        <mat-card-header>
    <mat-card> 
</ng-container>

<ng-container> is a special Angular template element which will never appear in the DOM. It's useful for logical complexities like this one.

For more info, see https://angular.io/api/core/ng-container

CodePudding user response:

In Angular, you cannot use 2 structure directives on one element. in this case, ngFor and CustomFeature are structure directives. The reason is Angular don't know what template it should render for you because 2 directive have difference condition and logic template.

So you can wrap mat-card with ng-container to avoid that error.

<ng-container *ngFor="let todo of todos">
    <mat-card *customFeature="todo.id">
        <mat-card-header>
            <mat-card-title>{{{todo.title}}</mat-card-title>
        <mat-card-header>
    <mat-card> 
</ng-container>
  • Related