Угловое обновление - нельзя использовать обновленный компонент в качестве входного компонента

Я использую модуль Angular Upgrade с компонентами, обновленными с AngularJS. Когда я использую компоненты внутри шаблонов, они работают нормально, но когда я пытаюсь использовать их в качестве компонентов ввода, я получаю сообщение об ошибке:

MyNgComponent cannot be used as an entry component.

Вероятно, это потому, что обновленные компоненты определены как директивы. Я также пытался обернуть в другой компонент, но в этом случае он выдает ошибку при попытке создать экземпляр компонента:

NullInjectorError: No provider for $scope!

$scope запрашивается внутренней реализацией UpgradeComponent и разрешается нормально, если компонент используется в шаблоне.

Это гибридное ограничение режима или есть ли способ использовать его в качестве компонента входа?

Компонент ввода необходим, потому что мне нужно создать экземпляр этого компонента из JS и вручную подключить к неугловому элементу DOM

0 ответов

Кажется, это ограничение гибридного режима. В моем случае необходимо было динамически создавать обновленные компоненты и подключать их к DOM. В этом случае можно использовать следующий обходной путь:

  1. Создайте обычный угловой компонент в качестве оболочки для обновленной директивы AngularJS, чтобы его шаблон содержал только обновленную директиву
  2. Добавьте этот компонент оболочки в entryComponents раздел модуля
  3. Динамически создать экземпляр этого компонента-оболочки с помощью инжектора корневого гибридного компонента

Например, у меня есть фиктивная директива AngularJS

angular.module('app').component('myComponent', {
  template: 'dummy content',
  controller: class {},
  controllerAs: 'vm'
});

@Directive({
  selector: 'my-component'
})
export class MyUpgradedDirective extends UpgradeComponent {
  constructor(elementRef: ElementRef, injector: Injector) {
    super('myComponent', elementRef, injector);
  }
}

Создайте компонент оболочки:

@Component({
  selector: 'app-nested',
  template: '<my-component></my-component>'
})
export class WrapperComponent { }

Добавьте это к entryComponents

@NgModule({
  imports:      [ BrowserModule, UpgradeModule ],
  declarations: [ AppComponent, NestedComponent, MyUpgradedDirective ],
  entryComponents: [ AppComponent, NestedComponent ] // here
})

Создайте экземпляр оболочки, используя инжектор из корневого гибридного компонента:

function createMyComponent<T>(componentFactoryResolver: ComponentFactoryResolver, injector: Injector /* must be passed from root hybrid component */, component: Type<T>) {
  return componentFactoryResolver
    .resolveComponentFactory(component)
    .create(injector);
}

Вот некоторые подробности: https://github.com/angular/angular/issues/27432

Другие вопросы по тегам