Search code examples
angularjsangularupgradeangular2-changedetectionng-upgrade

Change detection not working in downgraded Angular components


I'm in the process of converting a rather big application written in AngularJS to an Angular application using the @angular/upgrade module. For now, every component from AngularJS is running as expected in the Angular app. The app is being bootstrapped like this:

export class AppModule {
    constructor(
        private upgradeModule: UpgradeModule,
    ) {}

    ngDoBootstrap() {
        this.upgradeModule.bootstrap(
            document.body,
            ['myApp'],
            { strictDi: true },
        )
    }
}

However, I've started to rewrite components in Angular and I've run into problems trying to get those downgraded components to work. I'm using ui-router to map components to states like this:

function config($stateProvider) {
    $stateProvider.state('some-state', {
        parent: 'app',
        views: {
            content: {
                component: 'someComponent'
            }
        },
        url: '/some-state'
    })
}

The rewritten component is being downgraded like this:

angular
   .module('myApp')
   .directive(
       'someComponent',
       downgradeComponent({ component: SomeComponent }),
   )

SomeComponent is just a regular Angular component.

It shows up fine, the template is being rendered and everything, however, change detection doesn't seem to be working. The change detector seems to run once shortly after the view is being rendered, after that however, it doesn't ever run again unless i call it manually. NgZone.isInAngularZone() returns false if run anywhere within the downgraded component, I'm not sure if this is intended or not. If I inject ChangeDetectorRef and run detectChanges on any methods that change the fields of the component, the updates are being detected and rendered just fine. However, it would be way too much work in the long run to append an (input)="changeDetectorRef.detectChanges()" to every input, and call detectChanges() in pretty much any function that does anything.

Is there anything I am missing? If I haven't provided enough information, I can try to get a minimal reproduction of the problem running, this would probably be a bit of work though, so I want to ask like this first.


Solution

  • Ok, so the answer turned out to be something really simple. While I upgraded everything individually, I copied over most of the old index.html, which still contained ng-app="myApp" on the body tag.

    This caused the AngularJS app to bootstrap itself in the HTML instead of the Angular app handling the bootstrapping, which prevented the AngularJS app from running in the NgZone. I'm leaving this here for anyone who makes the same mistake. In short, make sure you've removed the old ng-app-tag from your index.html.