Migration from ng-metadata 1.x to 2.0
bootstrap changes
- platform module endpoint was renamed from
ng-metadata/platform
tong-metadata/platform-browser-dynamic
to mirror intention and Angular 2 changes ( Angular 1 is always dynamic ) boostrap
has different API(RootComponent: Type, customProviders?: Array<any|Type|string|any[]>)
BEFORE (1.x):
// app.component.ts
import { Component } from 'ng-metadata/core';
@Component({
selector: 'app',
template: '...'
})
export class AppComponent { }
// index.ts
import * as angular from 'angular';
import * as ThirdPartyModule from 'foo-bar';
import { provide } from 'ng-metadata/core';
import { SomeOldAngularModule } from './modules';
import { AppComponent } from './app.component';
export const AppModule = angular.module('app', [SomeOldAngularModule, ThirdPartyModule])
.directive( ...provide(AppComponent) )
.name;
// main.ts
import { bootstrap } from 'ng-metadata/platform';
import { AppModule } from './index';
bootstrap( AppModule );
NOW (2.0):
// app.component.ts
import { Component } from 'ng-metadata/core';
@Component({
selector: 'app',
template: '...'
})
export class AppComponent { }
// main.ts
import { bootstrap } from 'ng-metadata/platform-browser-dynamic';
import * as ThirdPartyModule from 'foo-bar';
import { SomeOldAngularModule } from './modules';
import { AppComponent } from './app.component';
bootstrap( AppComponent, [SomeOldAngularModule,ThirdPartyModule] )
app parts registration changes
ng-metadata 2.0 comes with Angular 2 style of application instantiation. ( high five on that !)
That means that from now on the preferred way to register things is via @Component/@Directive providers
/viewProviders
/directives
/pipes
property metadata
But don't worry you don't have to rewrite everything! you can of course do that gradually.
Basic step is to create root AppComponent if you don't have one, and boot it via new bootstrap
function .
Then your other modules and component registered via angular.module
and service/directive/value/constant/config
can be provided as 2nd argument of bootstrap
function and you can gradually upgrade things until angular.module
and provide
are completely removed.
See Playground for real life example how this hybrid works ;)
For further reference check broad overview guide
templates changes
- if you don't provide binding type
=
/<
/@
explicitly within @Input decorator, it will be determined from template. You can combine both approaches, but we recommend to be consistent
For further reference check broad overview guide
Note:
@Output()
can consume both(on-foo)="$ctrl.foo()
oron-foo="$ctrl.foo()
@Output changes
- before @Output onFoo, was wrapped within abstract EventEmitter if you created new instance directly or not.
So you were able to call that property directly with locals payload
this.onFoo({$event:'hello'})
or via monkey patched emitter under the hoodthis.onFoo.emit('hello')
- now EventEmitter is real RxJS Subject back-ported from Angular 2, so those magical things won't work anymore
Update is pretty easy, assign all @Output to new EventEmitter()
and instead of calling that functions call propName.emit()
BEFORE (1.x):
import { Component, Output } from 'ng-metadata/core';
@Component({
selector: 'my-child',
template: `<button ng-click="$ctrl.doSomething()">click me </button>`,
})
class ChildComponent{
@Output() onFoo: Function;
doSomething(){
this.onFoo({name:'Martin'})
}
}
@Component({
selector: 'my-app',
template: `<my-child on-foo="$ctrl.clicked(name)"></my-child>`
})
class AppComponent{
clicked(name){
console.log(name);
}
}
NOW (2.0):
import { Component, Output, EventEmitter } from 'ng-metadata/core';
@Component({
selector: 'my-child',
template: `<button ng-click="$ctrl.doSomething()">click me </button>`,
})
class ChildComponent {
@Output() onFoo = new EventEmitter<string>();
doSomething(){
this.onFoo.emit('Martin');
}
}
@Component({
selector: 'my-app',
template: `<my-child (on-foo)="$ctrl.clicked($event)"></my-child>`,
directives: [ChildComponent]
})
class AppComponent{
clicked(name){
console.log(name);
}
}