Angular downgradeComponent not being created

2019-08-05 06:17发布

I have just setup a hybrid AngularJS / Angular 5 application with downgradeModule. I have converted a very small component from AngularJS to Angular but it is never being created. I have put console.logs throughout the component to see if certain bits are called and others not. The file is loaded but the component never is.

I have read what feels like hundreds of tutorials but I must be missing something.

Note that I got this far in converting the component, realised it was not being created, then stopped porting the rest. Hence why driverImage is not currently on the converted component.

Here is a stackblitz with a test component that shows it not working https://angularjs-q1vrpe.stackblitz.io/

Bootstrap

import * as angular from "angular";

import { downgradeModule } from "@angular/upgrade/static";
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import { StaticProvider } from "@angular/core";

import { MainAngularModule } from "./app.module";
import "./index.module";

const bootstrapFn = (extraProviders: StaticProvider[]) => {
    console.log("1"); <--- never output!
    const platformRef = platformBrowserDynamic(extraProviders);
    return platformRef.bootstrapModule(MainAngularModule);
};

const downgradedModule = downgradeModule(bootstrapFn);

angular.module('angularJsModule', ['myApp', downgradedModule]);

angular.bootstrap(document, ['angularJsModule']);

App.Module (MainAngularModule)

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { UpgradeModule } from '@angular/upgrade/static';

@NgModule({
    imports: [
        BrowserModule,
        UpgradeModule
    ],
    declarations: [Ng2TestComponent, DriverImageComponent],
    entryComponents: [Ng2TestComponent, DriverImageComponent]
})

export class MainAngularModule {
    // Empty placeholder method to satisfy the `Compiler`.
    ngDoBootstrap() { }
}

index.module (Stripped most of the dependencies out for brevity)

angular
    .module("myApp", [
        "constants",
        "ngMaterial",
        "ngSanitize", ... ]);

The newly converted Component:

import { Component, Input, OnInit, OnChanges } from '@angular/core';
import { IDriver } from "../interfaces/IDriver";

console.log("here"); // --> This is hit

@Component({
    selector: "driver-image",
    template: `<div class="driver-image" ng-style="{'background-image' : 'url('+$ctrl.driverImage+')'}"></div>`
})

export class DriverImageComponent implements OnInit, OnChanges {
    @Input() driver: IDriver;
    @Input() small: boolean;

    constructor() {
        console.log("1"); // --- Not hit
    }

    ngOnInit() {
        console.log("ONINITNINTT"); // --> Not hit
    }

    ngOnChanges() { }
}

The related modules.ts

import { downgradeComponent } from "@angular/upgrade/static";
...
.component("driverImage", downgradeComponent({ component: DriverImageComponent }))

2条回答
戒情不戒烟
2楼-- · 2019-08-05 06:42

The answer is actually really simple, it just took me forever to see it.

Contrary to what you might believe, you need to change your AngularJS component to be registered as a directive, NOT, a component.

查看更多
淡お忘
3楼-- · 2019-08-05 06:51

without a Stackblitz this is pretty hard to reproduce (btw do you have any errors in the console?). I just write down some suggestions that you can try. If you tell me what worked, I'll update my answer

instead of import { platformBrowser } from "@angular/platform-browser"; use this one instead import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; (can't quite tell you the difference but platform-browser does not work in my projects)

Ok while writing this I think I found the answer. Your problem is you are not loading the component that should be downgraded in your Angular 5 application - everything you want to downgrade still needs to be properly loaded in Angular 5 itself. So try adding a entryComponents: [DriverImageComponent] to your App.Module

Edit:

Ok based on your comment it looks like your Application is not even bootstrapped. Are you sure you are using your component on the page that you are currently using? If the component is not being used, it will not be loaded and Angular won't be bootstrapped.

There are certain scenarios where you need to force this bootstrapping in the beginning.

Create an Bootstrap component

import { Component } from '@angular/core';

@Component({
    selector: 'my-bootstrap',
    template: '',
})
export class BootstrapComponent {}

Add it to your App.Module

declarations: [
    BootstrapComponent,
],
entryComponents: [
    BootstrapComponent,
],

Force it to be loaded in your main index.html by adding <my-bootstrap></my-bootstrap in the beginning of the <body>

查看更多
登录 后发表回答