动态呈现HTML

时间:2018-07-03 08:56:37

标签: angular p3x-angular-compile

我正在尝试在Angular中动态呈现包含HTML标记的字符串。 HTML应该是“ Angular编译的”,即包括数据绑定和组件的呈现(我在AngularJS中使用$compile做的事情)。

我大部分使用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”是Angular组件,则请验证它是否属于此模块。   2.如果“ app-sc-navbar”是Web组件,则将“ CUSTOM_ELEMENTS_SCHEMA”添加到该组件的“ @ NgModule.schemas”   禁止显示此消息。

组件(ScNavbarComponent)是app模块声明的一部分,并且-如果用于静态标记中,则可以正常工作。

我在这里想念什么?如何使动态呈现了解ScNavbarComponent

编辑:

这是完整的调试器输出:

output

我尝试将ScNavbarComponent添加到导出和/或entryComponents。

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

1 个答案:

答案 0 :(得分:2)

如果要在一个模块中声明组件,然后在另一个模块中使用它们,则需要导出,以便能够将模块导入另一个模块。

在您的 app.module.ts 中声明并导出它们,以便您的其他模块可以理解这些来自其他模块。

 @NgModule({
  imports: [
    BrowserModule
  ],

  declarations: [
    AppComponent,
    ScNavbarComponent
  ],

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

 }

在其他模块中,您现在可以导入 ScNavbarComponent

但是,如果您没有其他模块,则可以将 ScNavbarComponent 添加到 app.module.ts 的entryComponents部分。如果还不存在,则可以按如下所示添加它。

entryComponents: [
    ScNavbarComponent
  ]

编辑:

您可能会考虑做的事情(可能更适合您的目标)是使用ComponenFactoryResolver,它可以动态渲染Angular Components。下面是一个如何工作的示例:

在模板中,您可以使用模板引用,例如:

<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中。

我希望这会有所帮助!