I’m wrapping up Meteor and the latest Ionic 2.0.0-rc.0. I migrated my app from Ionic beta.11, got a NgModule like this:
//app.module.ts
@NgModule({
declarations: [
SkyFrame
],
imports: [
IonicModule.forRoot(SkyFrame),
],
bootstrap: [IonicApp],
entryComponents: [
SkyFrame
],
providers: [
METEOR_PROVIDERS
]
})
export class AppModule {
}
//main.ts
Meteor.startup(function(): void {
if (Meteor.isProduction) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule);
});
//app.component.ts
@Component({
templateUrl: 'app.component.html',
})
export class SkyFrame implements OnInit {
constructor() {
}
ngOnInit():void {
console.info('This will print endlessly in the console');
}
}
And when the app starts things go wrong and the call stack is full immediately.
core.umd.js:3372 ORIGINAL EXCEPTION: Maximum call stack size exceeded
When I look at the constructed DOM things go very interesting!
<ion-app>
expands into infinite tree with 2 roots! Basically I have two times ng-component
which renders itself recursively. I could expand this tree more but would never be able to take whole picture of it
What I’ve found in Ionic’s code is that the following is repeated thousand of times
//app-root.ts
ngOnInit() {
// load the user root component
// into Ionic's root component
const factory = this._cfr.resolveComponentFactory(this._userCmp);
const componentRef = this._viewport.createComponent(factory);
this._renderer.setElementClass(componentRef.location.nativeElement, 'app-root', true);
componentRef.changeDetectorRef.detectChanges();
//change detected!! repeat here (insert another ng-component into any found app-root)
...
Nailing it further down createComponent
is responsible for rendering:
ViewContainerRef_.prototype.createComponent = function (componentFactory, index, injector, projectableNodes) {
if (index === void 0) { index = -1; }
if (injector === void 0) { injector = null; }
if (projectableNodes === void 0) { projectableNodes = null; }
var s = this._createComponentInContainerScope();
var contextInjector = isPresent(injector) ? injector : this._element.parentInjector; //contextInjector becomes the parentInjector!
var componentRef = componentFactory.create(contextInjector, projectableNodes);
this.insert(componentRef.hostView, index);
return wtfLeave(s, componentRef);
};
So parent context is always injected into my component. this._element.parentInjector
here is the injector of the root view (<html>
)
Not sure if I screwed something up or it’s Ionic bug or it’s Angular. Especially when I’m trying to integrate it all with Meteor. Thus this question posted here not in Ionic’s GitHub.
This combination of libraries is quite fresh so I’m just posting it just in case someone got the same problem.
Package dependencies:
"dependencies": {
"@angular/common": "2.0.2",
"@angular/compiler": "2.0.2",
"@angular/core": "2.0.2",
"@angular/forms": "2.0.2",
"@angular/http": "2.0.2",
"@angular/platform-browser": "2.0.2",
"@angular/platform-browser-dynamic": "2.0.2",
"@angular/router": "3.0.2",
"angular2-meteor": "0.7.0",
"angular2-meteor-accounts-ui": "0.8.0",
"angular2-meteor-polyfills": "^0.1.1",
"es6-shim": "0.35.1",
"ionic-angular": "^2.0.0-rc.0",
"ionicons": "3.0.0",
"meteor-node-stubs": "0.2.3",
"reflect-metadata": "0.1.8",
"rxjs": "5.0.0-beta.12",
"zone.js": "^0.6.23"
}