How to use Angular structural directive with multiple inputs

e-cloud picture e-cloud · Jan 22, 2017 · Viewed 14.5k times · Source

I want to implement something similar with angular-permisssion. And with requirement to control the element's existance, I need to use angular structural directive.

At the beginning, i think such syntax would work:

<h2 *permissionIf [permissionIfExcept]="'Read'">Except</h2>

However, it doesn't work that way.

Moreover, the offical guide only teach you how to write custom structural directive with single input. With multi-inputs, some third-party tutorials involve a bit. But that's using the angular template micro-syntax to achieve data binding. Then one problem occurs: template syntax doesn't support pure key-value inputs:

<h2 *permissionIf="except: map.except;only: 'test'">Except</h2>

It expands into this(which is illegal):

<h2 template="permissionIf except: map.except;only: 'test'">Except</h2>

A stupid temporary solution is add a useless variable declaration.

<h2 *permissionIf="let i;except: map.except;only: 'test'">Except</h2>

Another inconvenient way is to use template element to wrap the code.

<template permissionIf [permissionIfExcept]="'Read'">
  <h2>Except</h2>
</template>

The above all are not accepetable enough. But I can't find a bette way to resolve it.

Hope some guys can give some suggestion:).

Answer

G&#252;nter Z&#246;chbauer picture Günter Zöchbauer · Jan 22, 2017

The input names need all to be prefixed with the selector of the directive, followed by the input name capitalized (i.e. permissionIfExcept). Example:

  @Directive({
    selector: '[permissionIf]'
  })
  export class PermissionIfDirective implements AfterContentInit {

    private _permissionIf:string[];
    @Input() 
    set permissionIf(value: string[]) {
      this._permissionIf=value;
      console.log('permissionIf: ', value);
    }

    private _except:string;
    @Input() 
    set permissionIfExcept(value: string) {
      this._except = value;
      console.log('except: ', value);
    }
  }

To use them with the '*' syntax:

<div *permissionIf="permissions;except:'Read'"></div>

Note here you're using the name following the prefix uncapitalized (i.e. except). Also note the : in the assignment.

The explicit syntax (using template) would look like this:

<template [permissionIf]="permissions" [permissionIfExcept]="'Read'">
  </div></div>
</template>

but with <ng-container> it could look like

<ng-container *permissionIf="permissions;except:'Read'">
  <div></div>
</ng-container>

Plunker example

See also the source of NgFor as an example.