I have a hybrid angular-cli that roughly follows Victor Savkin's Lazy Loaded AngularJS guide. AngularJS is bootstraped in the constructor of a LazyLoaded Angular module. The main difference between my app and the guide is that I am trying to wrap the <ui-view>
directive inside of some Angular components. Because of how my layout is structured the <ui-view>
element will not be available when AngularJS is bootstrapped and may be added or removed at any time.
import { Component, Directive, ElementRef, Injector } from '@angular/core';
import { UpgradeComponent } from '@angular/upgrade/static';
import * as angular from 'angular';
@Component({
template: `
<layout-wrapper>
<my-toolbar></my-toolbar>
<layout-contents>
<ng2-ui-view>
<h3 class="text-center">AngularJS page not loaded</h3>
</ng2-ui-view>
</layout-contents>
</layout-wrapper>
`,
})
export class LegacyOutputComponent { }
@Directive({selector: 'ng2-ui-view'})
export class UpgradedUiViewComponent extends UpgradeComponent {
constructor(ref: ElementRef, inj: Injector) {
super('uiViewWrapper', ref, inj);
}
}
export const routerPatchModule = 'arcs.router.patch';
// We need to define a wrapper for ui-view because we can only upgrade
// components with only one definition. uiView cannot be automatically
// upgraded because its definition is too complex
angular.module(routerPatchModule, ['ui.router'])
.component('uiViewWrapper', { template: '<ui-view></ui-view>'})
When I run the code a Error: No provider for $scope!
error is thrown. Checking the stack trace I can see that it is thrown in the UpgradeComponent
super class. The injector tries to get $scope
and
This setup will not work. AngularJS needs to be able to load in the root of your application in order for the scope to be defined correctly.
A better way to approach this problem is to use the
<div ui-view>
directive in the root of your application (as in the upgrade guide) and then to downgrade a layout component from Angular into AngularJS to wrap your content.