首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有事件发射器的Angular Dynamic Html模板组件

具有事件发射器的Angular Dynamic Html模板组件
EN

Stack Overflow用户
提问于 2019-05-24 00:10:37
回答 1查看 328关注 0票数 1

我试图通过添加一个通用的事件发射器来扩展这个组件的功能

代码语言:javascript
复制
import {
  Component,
  Directive,
  NgModule,
  Input,
  ViewContainerRef,
  Compiler,
  ComponentFactory,
  ModuleWithComponentFactories,
  ComponentRef,
  ReflectiveInjector
} from '@angular/core';

import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';

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

  @NgModule({ imports: [CommonModule, RouterModule], 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();
    }
  }
}

归功于原始作者https://gist.github.com/benjamincharity/8116414c7f38cffe3cef0e44fe44295d

所需事件的示例

代码语言:javascript
复制
@Output() genericEventEmitter = new EventEmitter<string>();

emitEvent(data:string){
this.genericEventEmitter.emit(data)
}

我尝试将此代码添加到htmlOutlet类和DynamicComponent中,得到了错误消息

代码语言:javascript
复制
ERROR TypeError: _co.emitEvent is not a function
    at Object.eval [as handleEvent] (DynamicComponent.html:6)

这告诉我,在componentFactory中创建函数时,没有正确地将其添加到类中

有没有什么尖刻的上师,能给我一些关于如何让它工作的见解?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-28 22:01:18

管理以菊花链形式将动态组件中的主题链接到html出口中的事件发射器,该事件发射器可由html出口的父节点捕获。

代码语言:javascript
复制
import {
  Component,
  Directive,
  NgModule,
  Input,
  ViewContainerRef,
  Compiler,
  ComponentFactory,
  ModuleWithComponentFactories,
  ComponentRef,
  ReflectiveInjector,
  EventEmitter,
  Output,


} from '@angular/core';
import { Observable, Subject } from 'rxjs'

import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { PartialObject } from 'lodash';

export function createComponentFactory(compiler: Compiler, metadata: Component): Promise<ComponentFactory<any>> {
  const cmpClass = class DynamicComponent {
    outputter: Subject<Object> = new Subject();
    genEmit(data) {
      this.outputter.next(data)
    }

  };
  const decoratedCmp = Component(metadata)(cmpClass);

  @NgModule({ imports: [CommonModule, RouterModule], 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>;
  @Output() genericEmitter = new EventEmitter();


  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, []);
        this.cmpRef.instance.outputter.subscribe(v => {
          this.genericEmitter.emit(v)

        })



      });

  }

  ngOnDestroy() {
    if (this.cmpRef) {
      this.cmpRef.destroy();
    }
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56279217

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档