是否有可能在Http响应后运行组件?

时间:2018-01-10 16:43:22

标签: angular

我正在连接自己的API。此API返回一个JSON响应,其中包含一些带有Angular组件标记的文本,如:

<app-heroes></app-heroes>

一旦我输出到html文件,它不会渲染组件?我收到http get请求后是否有可能呈现组件?我认为在AngularJs中有可能使用$ compile。

它确实将标记呈现为html,但它不会呈现组件。

谢谢!

编辑:我正在使用版本5.1

3 个答案:

答案 0 :(得分:1)

创建一个这样的自定义指令。

export function createComponentFactory(compiler: Compiler, metadata: Component): Promise<ComponentFactory<any>> {
    const cmpClass = class DynamicComponent {};
    const decoratedCmp = Component(metadata)(cmpClass);

    @NgModule({ imports: [CommonModule, RouterModule, SharedModule], declarations: [decoratedCmp] })
    class DynamicHtmlModule { }

    return compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule)
       .then((moduleWithComponentFactory: ModuleWithComponentFactories<any>) => {
        return moduleWithComponentFactory.componentFactories.find(x => x.componentType === decoratedCmp);
      });
}

@Directive({ selector: 'html-outlet' })
export class HtmlOutlet {
  @Input() html: string;
  cmpRef: ComponentRef<any>;

  constructor(private vcRef: ViewContainerRef, private compiler: Compiler) { }

  ngOnChanges() {
    const html = this.html;
    if (!html) return;

    if(this.cmpRef) {
      this.cmpRef.destroy();
    }

    const compMetadata = new Component({
        selector: 'dynamic-html',
        template: this.html,
    });

    createComponentFactory(this.compiler, compMetadata)
      .then(factory => {
        const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector);   
        this.cmpRef = this.vcRef.createComponent(factory, 0, injector, []);
      });
  }

  ngOnDestroy() {
    if(this.cmpRef) {
      this.cmpRef.destroy();
    }    
  }
}

现在从组件传递html作为您要呈现的指令的输入

@Component({
  selector: 'my-home',
  template: `
    <h1>home</h1>
    <html-outlet [html]="value"></html-outlet>
  `
})
export class HomeComponent {
  value = `<app-heroes></app-heroes>`;
}

Demo

答案 1 :(得分:1)

尝试在div上使用innerHTML属性,例如:

<div [innerHTML]="customHTML"></div>

customHTML是API的响应,例如<app-heroes></app-heroes>innerHTML属性绑定div

中的HTML字符串

答案 2 :(得分:0)

从API获取文本并将其显示为组件是可能的,但有点hacky和硬编码。

这就是我要做的事。

@Component({
  selector: 'some-component',
  template: `
     <h1> Some Component </h1>
    <app-heroes *ngIf="textToComponent  === '<app-heroes></app-heroes>'" > </app-heroes/>
  `
})
export class SomeComponent {
   constructor(){
        this.getData();
   }
  textToComponent= `<app-heroes></app-heroes>`;

//call your api here and set the textToComponent;
   getData(){
   }
}

我在这里做的是我已经在模板中添加了其他组件并使用*ngIf进行切换。我不确定你到底想要的是什么。 如果您需要高级解决方案,请尝试寻找创建动态组件。

此处还有stackblitz demo来自上方。