问题
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
回答1:
Alternative is to let Angular know that it needs to provide the $scope
.
import { Injector } from '@angular/core';
// allow $scope to be provided to ng1
export const ScopeProvider = {
deps: ['$injector'],
provide: '$scope',
useFactory: (injector: Injector) => injector.get('$rootScope').$new(),
};
@Directive({
providers: [ ScopeProvider ],
selector: 'ng2-ui-view',
})
export class UpgradedUiViewComponent extends UpgradeComponent {
constructor(ref: ElementRef, inj: Injector) {
super('uiViewWrapper', ref, inj);
}
}
回答2:
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.
来源:https://stackoverflow.com/questions/46008812/angular-upgradecomponent-cannot-find-scope