angular's ng-init alternative in Angular 2

You can use a directive

@Directive({
  selector: 'ngInit',
  exportAs: 'ngInit'
}) 
export class NgInit {
  @Input() values: any = {};

  @Input() ngInit;
  ngOnInit() {
    if(this.ngInit) { this.ngInit(); }
  }  
}

you can use it to pass a function to be called like

<div [ngInit]="doSomething"

or to make values available

<div ngInit [values]="{a: 'a', b: 'b'}" #ngInit="ngInit">
  <button (click)="clickHandler(ngInit.values.a)">click me</button>
</div>
  • ngInit addes the directive
  • [values]="{a: 'a', b: 'b'}" sets some initial values
  • #ngInit="ngInit" creates a reference for later use
  • ngInit.values.a reads the a value from the created reference.

See also Converting Angular 1 to Angular 2 ngInit function


Another approach is by using the @Output decorator and EventEmitter:

import {Directive, OnInit, Output, EventEmitter} from '@angular/core';

@Directive({
    selector: '[ngInit]'
})
export class NgInitDirective implements OnInit {

    @Output()
    ngInit: EventEmitter<any> = new EventEmitter();

    ngOnInit() {
        this.ngInit.emit();
    }
}

And then use it like:

<div *ngIf="condition" (ngInit)="initialize()">  ... </div>

Demo


@Directive({
  selector: '[ngxInit]',
})
export class NgxInitDirective {
  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef) {
  }

  @Input() set ngxInit(val: any) {
    this.viewContainer.clear();
    this.viewContainer.createEmbeddedView(this.templateRef, {ngxInit: val});
  }
}

a value expression is set via *ngxInit and published using as micro-syntax:

<div *ngxInit="3 * i + j as idx">{{idx}}</div>

published as https://www.npmjs.com/package/ngx-init