'foo' не является известным элементом при динамическом рендеринге HTML - PullRequest
0 голосов
/ 03 июля 2018

Я пытаюсь динамически визуализировать строку, содержащую разметку HTML в Angular. HTML-код должен быть 'Angular-скомпилирован', то есть включать привязку данных и рендеринг компонентов (то, что я делал с $compile в AngularJS).

У меня большая часть работы с использованием p3x-angular-compile :

<div [p3x-compile]="Template.Source" [p3x-compile-ctx]="Data"></div>

работает как положено и правильно отображает Template.Source, т. Е .:

this.Template.Source = '<p>Hello</p>';

, а также

this.Template.Source = '<p>{{Foo}}</p>';

где Foo является свойством связанного Data объекта.

Однако, рендеринг моих собственных угловых компонентов не работает:

this.Template.Source = '<app-sc-navbar></app-sc-navbar><p>Other arbitrary markup anywhere in string'</p>;

выдает ошибку:

CompileAttribute.js: 80

Ошибка: ошибки синтаксического анализа шаблона: «app-sc-navbar» не является известным элементом: 1. Если app-sc-navbar является угловым компонентом, то убедитесь, что он является частью этого модуля. 2. Если 'app-sc-navbar' является веб-компонентом, то добавьте 'CUSTOM_ELEMENTS_SCHEMA' к '@ NgModule.schemas' этого компонента. подавить это сообщение.

Компонент (ScNavbarComponent) является частью объявлений модуля приложения и, если используется в статической разметке, работает нормально.

Что мне здесь не хватает? Как я могу сделать динамический рендеринг осведомленным о ScNavbarComponent?

EDIT:

Это полный вывод отладчика:

output

Я попытался добавить ScNavbarComponent к экспорту и / или элементу entry.

@NgModule({
  declarations: [
    AppComponent,
    ScNavbarComponent,
    ...
  ],
  imports: [
    BrowserModule,
    ...
    CompileModule
  ],
  entryComponents: [
    ScNavbarComponent
  ],
  providers: [],
  bootstrap: [AppComponent],
  exports: [
    ScNavbarComponent
  ],
})
export class AppModule { }

1 Ответ

0 голосов
/ 03 июля 2018

Если вы хотите объявить компоненты в одном модуле и использовать их в другом модуле, вам нужно экспортировать их, чтобы иметь возможность импортировать модуль в другой модуль.

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

 @NgModule({
  imports: [
    BrowserModule
  ],

  declarations: [
    AppComponent,
    ScNavbarComponent
  ],

exports: [
      ScNavbarComponent
],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {

 }

В другом модуле вы теперь можете импортировать ScNavbarComponent .

Если у вас нет других модулей, вы можете просто добавить ScNavbarComponent в раздел entryComponents вашего app.module.ts . Если его там уже нет, вы можете просто добавить его, как показано ниже.

entryComponents: [
    ScNavbarComponent
  ]

EDIT:

Что-то, что вы могли бы подумать сделать (что могло бы лучше соответствовать вашей цели), это использовать ComponenFactoryResolver, который позволяет динамически отображать угловые компоненты. Ниже приведен пример того, как это может работать:

В вашем шаблоне вы можете использовать шаблон ref вроде:

<div #navbar></div>

Чтобы назначить компонент этой ссылке, в своем компоненте вы должны ссылаться на это с помощью аннотации ViewChild:

@ViewChild('navbar', { ViewContainerRef }) navBar: ViewContainerRef;

Далее вам нужно добавить сам преобразователь в ваш конструктор:

constructor(private resolver: ComponentFactoryResolver) {}

Резолвер теперь готов к использованию и должен использоваться в ловушке жизненного цикла ngAfterContentInit , как описано ниже (убедитесь, что ваш компонент реализует ngAfterContentInit):

ngAfterContentInit() {
  const navBarFactory = this.resolver.resolveComponentFactory(ScNavbarComponent); // make sure to import your component
  const component = this.navBar.createComponent(navBarFactory);
}

После реализации приведенного выше кода ваш ScNavbarComponent должен динамически проецироваться внутри вашего templateRef.

Надеюсь, это поможет!

...