Javascript 如何在Angular2中的模板html上呈现动态创建的数组组件?
我通过选择预先存在的组件创建了动态组件实例。比如说,Javascript 如何在Angular2中的模板html上呈现动态创建的数组组件?,javascript,angular,charts,angular2-template,Javascript,Angular,Charts,Angular2 Template,我通过选择预先存在的组件创建了动态组件实例。比如说, @Component({ selector: 'dynamic-component', template: `<div #container><ng-content></ng-content></div>` }) export class DynamicComponent { @ViewChild('container', {read: ViewContainerRef})
@Component({
selector: 'dynamic-component',
template: `<div #container><ng-content></ng-content></div>`
})
export class DynamicComponent {
@ViewChild('container', {read: ViewContainerRef}) container: ViewContainerRef;
public addComponent(ngItem: Type<WidgetComponent>,selectedPlugin:Plugin): WidgetComponent {
let factory = this.compFactoryResolver.resolveComponentFactory(ngItem);
const ref = this.container.createComponent(factory);
const newItem: WidgetComponent = ref.instance;
newItem.pluginId = Math.random() + '';
newItem.plugin = selectedPlugin;
this._elements.push(newItem);
return newItem;
}
}
chart-widget.component.html(使用primeng面板)
WidgetComponent.ts
@Component({
selector: 'widget',
template: '<ng-content></ng-content>'
})
export class WidgetComponent{
}
@组件({
选择器:“小部件”,
模板:“”
})
导出类WidgetComponent{
}
现在,我通过以下方式从现有组件(例如图表小部件和数据小部件)中选择一个组件来添加组件,并将实例存储到一个数组中
@Component({
templateUrl: 'main.component.html',
entryComponents: [ChartWidget, DataWidget],
})
export class MainComponent implements OnInit {
private elements: Array<WidgetComponent>=[];
private WidgetClasses = {
'ChartWidget': ChartWidget,
'DataWidget': DataWidget
}
@ViewChild(DynamicComponent) dynamicComponent: DynamicComponent;
addComponent(): void{
let ref= this.dynamicComponent.addComponent(this.WidgetClasses[this.selectedComponent], this.selectedComponent);
this.elements.push(ref);
this.dynamicComponent.resetContainer();
}
}
@组件({
templateUrl:'main.component.html',
entryComponents:[ChartWidget,DataWidget],
})
导出类MainComponent实现OnInit{
私有元素:数组=[];
私有WidgetClass={
“ChartWidget”:ChartWidget,
“DataWidget”:DataWidget
}
@ViewChild(DynamicComponent)DynamicComponent:DynamicComponent;
addComponent():void{
设ref=this.dynamicComponent.addComponent(this.WidgetClasses[this.selectedComponent],this.selectedComponent);
此.elements.push(ref);
this.dynamicComponent.resetContainer();
}
}
现在,我面临着在main.component.html中使用innerHtml呈现组件的问题。它呈现html,但我不能使用按钮单击事件或其他事件。我也尝试过使用素描绘制图表,但它也不起作用
main.component.html
<dynamic-component [hidden]="true" ></dynamic-component>
<widget *ngFor="let item of elements">
<div [innerHTML]="item._ngEl.nativeElement.innerHTML | sanitizeHtml">
</div>
</widget>
我还实现了一个sanitizeHtml管道,但它仍然给出相同的结果。因此,据我所知,innerHTML只显示html数据,但我不能使用任何按钮事件以及js图表。我还尝试在标记下显示类似于{{item}}的项。但它显示得像一个文本[对象]。那么,有人能给出一个解决方案吗?如何呈现允许按钮事件和js图表的组件?谢谢
编辑:在此处查看我的Plunker
您可以在这里看到,可以动态添加图表或数据小部件,我正在使用innerHTML显示它。因此,按钮事件在这里不起作用。如果我像{{item}}那样编码,那么它会显示[object]文本。您还可以在控制台中看到组件阵列数据。主要问题是,如何激活按钮上的按钮事件(例如,如果我单击关闭或刷新按钮,它将调用相关函数)?我将创建如下结构指令: view.directive.ts
import { ViewRef, Directive, Input, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[view]'
})
export class ViewDirective {
constructor(private vcRef: ViewContainerRef) {}
@Input()
set view(view: ViewRef) {
this.vcRef.clear();
this.vcRef.insert(view);
}
ngOnDestroy() {
this.vcRef.clear()
}
}
private elements: Array<{ view: ViewRef, component: WidgetComponent}> = [];
...
addComponent(widget: string ): void{
let component = this.dynamicComponent.addComponent(this.WidgetClasses[widget]);
let view: ViewRef = this.dynamicComponent.container.detach(0);
this.elements.push({view,component});
this.dynamicComponent.resetContainer();
}
然后
应用程序组件.ts
import { ViewRef, Directive, Input, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[view]'
})
export class ViewDirective {
constructor(private vcRef: ViewContainerRef) {}
@Input()
set view(view: ViewRef) {
this.vcRef.clear();
this.vcRef.insert(view);
}
ngOnDestroy() {
this.vcRef.clear()
}
}
private elements: Array<{ view: ViewRef, component: WidgetComponent}> = [];
...
addComponent(widget: string ): void{
let component = this.dynamicComponent.addComponent(this.WidgetClasses[widget]);
let view: ViewRef = this.dynamicComponent.container.detach(0);
this.elements.push({view,component});
this.dynamicComponent.resetContainer();
}
私有元素:数组=[];
...
addComponent(小部件:字符串):void{
让component=this.dynamicComponent.addComponent(this.WidgetClasses[widget]);
let view:ViewRef=this.dynamicComponent.container.detach(0);
this.elements.push({view,component});
this.dynamicComponent.resetContainer();
}
及
app.component.html
<widget *ngFor="let item of elements">
<ng-container *view="item.view"></ng-container>
</widget>
所以我刚刚将视图从动态组件容器移动到所需的位置
Plunker会很有帮助。通过
innerHTML创建的HTML不支持角度bindings@yurzui对这就是为什么我使用了消毒TML管道,但得到了相同的结果。我还尝试了{{item}}标记。但它像文本一样显示[对象]。嗨@yurzui,我给我的Plunker链接。你能检查一下并给我一个解决方案吗。谢谢你好,yurzui,谢谢你的支持。这对我有用。我用ng2 dragular的拖放功能稍微修改了代码。我使用两个数组,希望从一个容器拖放到另一个容器,最后希望保存两个数组值。但问题是,当我从一个容器拖动到另一个容器时,会出现类似“无法读取未定义的属性‘parent’”的错误。请看我的更新。你有什么解决办法吗?非常感谢。它似乎适用于我的版本:)太好了:)。谢谢。它工作得很好。所以,我必须换成角度4。angular2有什么解决办法吗?我已经用angular2版本完成了我项目的几个任务。所以,我想在这一刻继续讨论angular2。如果我能为angular2版本提供一些解决方案,那就太好了:)谢谢。嗨@yurzui,我已经将我的代码从angular2更新到了angular4。但我查错了密码。angular4未显示错误“无法读取未定义的属性'parent'”,但错误仍然存在。您可以在代码中看到,拖放后,它丢失了视图事件,而鼠标事件在这种情况下不起作用。只需测试一次或多次,就可以确定问题:)。如果能在这个问题上得到帮助,那就太好了。谢谢。它在一边工作,当我试着把它拖回到前一个位置时,它再次显示同样的错误。
<widget *ngFor="let item of elements">
<ng-container *view="item.view"></ng-container>
</widget>