Simon_Weaver
Simon_Weaver

Reputation: 146110

Custom Angular structural directive only works with asterisk syntax

I have created an Angular structural directive, but it only works with the * syntax and not the 'expanded' <ng-template> syntax.

Quick reminder :

When you put as asterisk in front of a structural directive, such as *ngIf="xxx" the template compiler expands it, so the following are equivalent:

<p *ngIf="condition">
  Our heroes are true!
</p>

<ng-template [ngIf]="condition">
  <p>
    Our heroes are true!
  </p>
</ng-template>

So I created my own directive (based on ngIf source code):

@Directive({
    selector: '[featureBoxLoader]'
})
export class FeatureBoxLoaderDirective {

    private _thenTemplateRef: TemplateRef<any>|null = null;

    constructor(private _viewContainer: ViewContainerRef, 
                private templateRef: TemplateRef<any>) 
    {
        this._thenTemplateRef = templateRef;
    }

    ngOnInit()
    {
        alert('yes it works!');
        this._viewContainer.createEmbeddedView(this._thenTemplateRef, { $implicit: { numbers: [1, 2, 3] } } );
    }
}

The directive is declared in my module, and when I use it like this it works fine:

  <div *featureBoxLoader>
     This is my feature box
  </div>

However when I do this I get an error:

 <ng-template [featureBoxLoader] let-data></ng-template>

The error is :

Can't bind to 'featureBoxLoader' since it isn't a known property of 'ng-template'. 1. If 'featureBoxLoader' is an Angular directive, then add 'CommonModule' to the '@NgModule.imports' of this component. 2. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.

What's happening? It's obviously finding it, but I need to use the <ng-template> syntax for let.

Upvotes: 1

Views: 1275

Answers (1)

Simon_Weaver
Simon_Weaver

Reputation: 146110

The difference is that in the *ngIf example you are providing a parameter (and also a corresponding @Input parameter in the ng_if directive implementation).

[ngIf]="condition"

The brackets are not necessary when you are just applying the directive without a condition.

So the correct syntax is just :

<ng-template featureBoxLoader let-data></ng-template>

Upvotes: 3

Related Questions