Angular 带有事件发射器的角度动态Html模板组件
我试图通过添加一个通用事件发射器来扩展这个组件的功能Angular 带有事件发射器的角度动态Html模板组件,angular,angular-factory,angular-compiler,Angular,Angular Factory,Angular Compiler,我试图通过添加一个通用事件发射器来扩展这个组件的功能 import { Component, Directive, NgModule, Input, ViewContainerRef, Compiler, ComponentFactory, ModuleWithComponentFactories, ComponentRef, ReflectiveInjector } from '@angular/core'; import { RouterModule
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();
}
}
}
这告诉我,在componentFactory中创建函数时,函数没有正确地添加到类中
任何有棱角的大师,都能对我如何实现这一点给出一些见解?设法将动态组件中的主题菊花链链接到html输出中的事件发射器,html输出的父级可以捕获该事件发射器
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();
}
}
}
导入{
组成部分,
指令,
NgModule,
输入,
ViewContainerRef,
编译程序,
组件工厂,
模块化组件工厂,
组件参考,
反射射束,
事件发射器,
产出,
}从“@angular/core”开始;
从“rxjs”导入{可观察,主题}
从'@angular/router'导入{RouterModule};
从“@angular/common”导入{CommonModule};
从“lodash”导入{PartialObject};
导出函数createComponentFactory(编译器:编译器,元数据:组件):承诺{
const cmpClass=类DynamicComponent{
输出:主题=新主题();
genEmit(数据){
this.outputter.next(数据)
}
};
const decoratedCmp=组件(元数据)(cmpClass);
@NgModule({imports:[CommonModule,RouterModule],声明:[decoratedCmp]})
类DynamicHtmlModule{
}
返回compiler.compileModule和AllComponentsAsync(DynamicHTML模块)
.然后((moduleWithComponentFactory:moduleWithComponentFactory)=>{
返回moduleWithComponentFactory.ComponentFactorys.find(x=>x.componentType===decoratedCmp);
});
}
@指令({selector:'html outlet'})
导出类HtmlOutlet{
@Input()html:string;
cmpRef:ComponentRef;
@Output()genericEmitter=neweventemitter();
构造函数(专用vcRef:ViewContainerRef,专用编译器:编译器){
}
ngOnChanges(){
const html=this.html;
如果(!html)返回;
if(this.cmpRef){
this.cmpRef.destroy();
}
const compMetadata=新组件({
选择器:“动态html”,
模板:this.html,
});
createComponentFactory(this.compiler,compMetadata)
。然后(工厂=>{
const injector=ReflectiveInjector.fromResolvedProviders([],this.vcRef.parentInjector);
this.cmpRef=this.vcreef.createComponent(工厂,0,注入器,[]);
this.cmpRef.instance.outputter.subscribe(v=>{
此.genericEmitter.emit(v)
})
});
}
恩贡德斯特罗(){
if(this.cmpRef){
this.cmpRef.destroy();
}
}
}
成功地将动态组件中的主题菊花链到html出口中的事件发射器,该事件发射器可由html出口的父级捕获
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();
}
}
}
导入{
组成部分,
指令,
NgModule,
输入,
ViewContainerRef,
编译程序,
组件工厂,
模块化组件工厂,
组件参考,
反射射束,
事件发射器,
产出,
}从“@angular/core”开始;
从“rxjs”导入{可观察,主题}
从'@angular/router'导入{RouterModule};
从“@angular/common”导入{CommonModule};
从“lodash”导入{PartialObject};
导出函数createComponentFactory(编译器:编译器,元数据:组件):承诺{
const cmpClass=类DynamicComponent{
输出:主题=新主题();
genEmit(数据){
this.outputter.next(数据)
}
};
const decoratedCmp=组件(元数据)(cmpClass);
@NgModule({imports:[CommonModule,RouterModule],声明:[decoratedCmp]})
类DynamicHtmlModule{
}
返回compiler.compileModule和AllComponentsAsync(DynamicHTML模块)
.然后((moduleWithComponentFactory:moduleWithComponentFactory)=>{
返回moduleWithComponentFactory.ComponentFactorys.find(x=>x.componentType===decoratedCmp);
});
}
@指令({selector:'html outlet'})
导出类HtmlOutlet{
@Input()html:string;
cmpRef:ComponentRef;
@Output()genericEmitter=neweventemitter();
构造函数(专用vcRef:ViewContainerRef,专用编译器:编译器){
}
ngOnChanges(){
const html=this.html;
如果(!html)返回;
if(this.cmpRef){
this.cmpRef.destroy();
}
const compMetadata=新组件({
选择器:“动态html”,
模板:this.html,
});
createComponentFactory(this.compiler,compMetadata)
。然后(工厂=>{
const injector=ReflectiveInjector.fromResolvedProviders([],this.vcRef.parentInjector);
this.cmpRef=this.vcreef.createComponent(工厂,0,注入器,[]);
this.cmpRef.instance.outputter.subscribe(v=>{
此.genericEmitter.emit(v)
})
});
}
恩贡德斯特罗(){
if(this.cmpRef){
this.cmpRef.destroy();
}
}
}
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();
}
}
}