7

As we all know there is no ng-init or something for Angular2. So if we try do do something like:

<div #rr="2+2">
 {{rr}}
</div>

We will get runtime error:

Error: There is no directive with "exportAs" set to "2+2"

I was watching one of the Angular2 dev videos on youtube and saw exactly the same construction meant to work. Here is the screenshot: enter image description here

How is this assignment to user template variable possible?

Dizzy
  • 892
  • 3
  • 12
  • 24

3 Answers3

5

#rr is not equivalent of ng-init. ng-init is gone and won't be back - you need to explicitly initialize fields in a component's class (equivalent of initalizing scope).

You can use exportAs property of the @Directive annotation. It exports the directive to be used in the parent view. From the parent view, you can bind it to a view variable and access it from the parent class using @ViewChild().

You can read up more on exportAs here.

Please check the sample demo for implementation of exportAs to here.

Santosh Shinde
  • 6,045
  • 7
  • 44
  • 68
2

Local variables aim to reference either the current DOM element:

<div #elt></div>

or a specific element applied on the element:

<div #elt="someDirective" dir></div>

someDirective corresponds to the exportAs value of the directive:

@Directive({
  selector: '[dir]',
  exportAs: 'someDirective'
})

You can't use them to define something else. This is what the message actually tells...

Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
1

In order to be able to declare variable within template you can leverage custom structural directive like:

@Directive({
  selector: '[ngInit]',
})
export class NgInitDirective {
  @Input()
  set ngInit(context: any) {
    this.context.$implicit = this.context.ngInit = context;
    this.vcRef.clear();
    this.vcRef.createEmbeddedView(this.templateRef, this.context);
  }

  context: { $implicit?: any, ngInit?: any } = {};

  constructor(private vcRef: ViewContainerRef, private templateRef: TemplateRef<any>) {}
}

After that your code can be written as follows:

<div *ngInit="2+2 as rr">
  {{rr}}
</div>

or

<div *ngInit="2+2; let rr">
  <span>{{rr}}</span>
</div>

Plunker Example

yurzui
  • 205,937
  • 32
  • 433
  • 399
  • Thanks for the directive. But if you see image or video from my 1st post that kind of notation is much clearer for someone reading your template. And the question was how it is possible? Still have no answer. – Dizzy Aug 08 '17 at 16:52