ng-metadata is the answer to upgrading to Angular 2
Earlier this week I spoke to making a poor man’s TypeScript Component decorator to begin to make Angular 1.x syntax more Angular 2.x compliant. Since then one of my coworkers brought to my attention a phenomenal library that extends on what I spoke to. ng-metadata is a library that allows you to wrap Angular 1.x code in TypeScript decorators to give the appearance of Angular 2 code. This is a huge benefit because it will allow for more gradual adoption of the Angular 2 specification.
This is a code snippet directly from ng-metadata that shows what your Angular 1.x Component code can be rewritten to look like
Angular 1.x with ngMetadata and Typescript:
// bootstrap.tsimport { bootstrap } from 'ng-metadata/platform';import { HeroModule } from './hero';bootstrap(HeroModule);// hero.tsimport * as angular from 'angular';import { provide } from 'ng-metadata/core';import { HeroComponent } from './hero.component';import { HeroService } from './hero.service';export const HeroModule = angular.module('hero', []).directive(...provide(HeroComponent)).service(...provide(HeroService)).name;// hero.service.tsimport { Injectable, Inject } from 'ng-metadata/core';@Injectable()export class HeroService {constructor(@Inject('$http') private $http: ng.IHttpService) {}fetchAll() {return this.$http.get('/api/heroes');}}// hero.component.tsimport { Component, Inject, Input, Output } from 'ng-metadata/core';import { HeroService } from './hero.service';@Component({selector: 'hero-cmp',templateUrl: 'hero.html',legacy: { transclude: true },})export class HeroComponent {@Input() name: string;@Output() onCall: Function;constructor(// we need to inject via @Inject because angular 1 doesn't give us proper types@Inject('$log') private $log: ng.ILogService,// here we are injecting by Type// which is possible thanks to reflect-metadata and Typescript and because our service// is defined as a classprivate heroSvc: HeroService) {}ngOnInit() {/* your init logic */}}
I have to admit, this is a very impressive port. The only real criticism I have of this port is that it does not support Angular 2’s providers array in the Component decorator.
// https://angular.io/docs/ts/latest/tutorial/toh-pt4.html// app/app.component.ts@Component({providers: [HeroService],})export class AppComponent implements OnInit {title = 'Tour of Heroes';heroes: Hero[];selectedHero: Hero;constructor(private heroService: HeroService) {}}
That being said I think that what the team at ng-metadata has done with the Inject decorator is rather ingenious. I like that you can designate a service as @Injectable and forgo showing any code in your @Component or you can opt for the more explicit route and use @Inject in the constructor to make the DI function more obvious to the end developer.
For a more detailed breakdown of ng-metadata’s capabilities, please visit their API docs
UPDATE: 6/16/16
I was incorrect. ng-metadata does have support for the providers array out of the box!
Property | DataType | Description |
---|---|---|
providers? | Array<Injectables|string> | Any providers that this component or any of it’s children depends on. This isn’t |
doing anything for now, just for visual experience and mirroring ng2 api |