简体   繁体   中英

Angular2 UpgradeComponent missing $injector

I am trying to upgrade an Angular1 component and consume it in my Angular2 app by following the official Angular2 documentation here under "Using Angular 1 Component Directives from Angular 2 Code", but it gives the following error:

error_handler.js:54 TypeError: Cannot read property 'get' of undefined
    at ChartDirective.UpgradeComponent (upgrade_component.js:97)

在此处输入图片说明

Upon closer inspection on line 97, this.$inspector is undefined:

在此处输入图片说明

My code is very simple:

import { Directive, ElementRef, Injector } from '@angular/core';
import { UpgradeComponent } from '@angular/upgrade/static';

export const coolComponent = {
  template: 'cool',
  controller: function() {
  }
};

@Directive({
    selector: 'app-chart'
})
export class ChartDirective extends UpgradeComponent {

    constructor(elementRef: ElementRef, injector: Injector) {
        super('coolComponent', elementRef, injector);
    }
}

My main.ts for bootstrapping is:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

Here is the simplified version of the problem, with minimal reproduction steps: https://github.com/dolanmiu/angular2-upgrade-test

It is generated by angular-cli

I had a similar problem. To fix my issue, I removed the following line from my AppModule definition:

bootstrap: [AppComponent]

In my case, I also had to add the AppComponent to my entryComponents section:

entryComponents: [AppComponent]

You also need to implement the ngDoBootstrap method, if you haven't already:

export class AppModule {
  ngDoBootstrap() {}
}

Here is a plunker of a working example I created. I was having the same issue as you described. The key for me was to downgrade my AppComponent and place the downgraded component into the Angular 1 app:

import { App1Component } from './app1.component';
import { App } from './app';
import { downgradeComponent } from '@angular/upgrade/static';

angular.module('ng1', [])
  .directive(
      'ng2AppComponent',
      downgradeComponent({component: App})
    )
  .component('app1Component', App1Component);

index.html:

...
<body>
   <ng2-app-component></ng2-app-component>
</body>
...

Then I needed to do as described above and move AppComponent to entryComponents in my AppModule.

@NgModule({
  imports: [ BrowserModule, UpgradeModule ],
  declarations: [ App, App1Directive ],
  entryComponents: [ App ]
})
export class AppModule {
  ngDoBootstrap() {}
}

In my example the downgraded Angular 2 AppComponent is in the index.html but you can place it in whatever Angular 1 template you want if that makes more sense for your application.

https://plnkr.co/edit/YSw63x10WAEivMWdNffj?p=preview

It can't use ng1 directive upgraded by UpgradeComponent,when you use ng2 to bootstrap your application.

You need use ng1 to bootstrap application and ng2 component,then use ng1 directive in ng2 component.

Which needs remove all content in bootstrap of @NgModule ,and move AppComponent to entryComponents ,then empty ngDoBootstrap() in AppModule:

@NgModule({
    bootstrap: [  ],
    //...
    entryComponents: [
        AppComponent,
        //...
    ]
})
export class AppModule {
    public ngDoBootstrap() {}
}

After that,downgrade AppComponent:

import { AppComponent } from '../app.component';
import { downgradeComponent } from '@angular/upgrade/static';
//...
angular.directive(
    'app', downgradeComponent({
        component: AppComponent
    }) as angular.IDirectiveFactory
);

And now,you can render a ng1 directive upgraded,in ng2 component.

More Details: Angular2 UpgradeComponent missing $injector

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM