typescript – Angular 2动态地将组件实例添加到容器中
发布时间:2020-12-17 17:26:31 所属栏目:安全 来源:网络整理
导读:我试图在Angular 2中实现一个ComponentContainer,这样你就可以动态添加其他组件,类似于 Android中的LinearLayout. 到目前为止,使用 Angular 2 dynamic tabs with user-click chosen components 我可以动态添加传递Type的组件. 我的问题是使用这个方法,创建的
我试图在Angular 2中实现一个ComponentContainer,这样你就可以动态添加其他组件,类似于
Android中的LinearLayout.
到目前为止,使用 我的问题是使用这个方法,创建的Component只是由它的Type创建,我不知道如何给它提供参数. 这就是我所做的: container.component.ts import { Component,OnChanges,AfterViewInit,OnDestroy,Input,Type,ViewChild,ViewContainerRef,ComponentRef,ComponentResolver,ComponentFactory } from '@angular/core'; @Component({ selector: 'wrapper-component',template: '<div #container></div>' }) class WrapperComponent implements OnChanges,OnDestroy { @Input() type: Type; @ViewChild('container',{read: ViewContainerRef}) container; cmpRef: ComponentRef<any>; private isViewInitialized: boolean = false; constructor(private resolver: ComponentResolver) { } private updateComponent() { if(!this.isViewInitialized) return; if(this.cmpRef) this.cmpRef.destroy(); this.resolver.resolveComponent(this.type).then((factory: ComponentFactory<any>) => { this.cmpRef = this.container.createComponent(factory); }) } ngOnChanges() { this.updateComponent(); } ngAfterViewInit() { this.isViewInitialized = true; this.updateComponent(); } ngOnDestroy() { if(this.cmpRef) this.cmpRef.destroy(); } } @Component({ selector: 'container-component',template: ` <wrapper-component *ngFor="let element of elements" [type]="element"> </wrapper-component> `,directives: [WrapperComponent] }) export class ContainerComponent { private elements: Type[] = []; visibility: boolean = true; Add(element: Type) { this.elements.push(element); } AddAll(elements: Type[]) { elements.forEach(element => { this.Add(element); }); } Clear() { this.elements = []; } } a1.component.ts import { Component,ViewChild } from '@angular/core' import { ContainerComponent } from '../../components/container.component'; @Component({ selector: 'child-component',template: '<div>a{{text}}</div>' }) class ChildComponent { text: string; } @Component({ selector: 'a1step',template: ` <button (click)="onClick()">Add</button> <container-component #container></container-component> `,directives: [ContainerComponent] }) export class A1Step { @ViewChild('container') container : ContainerComponent; onClick() { this.container.Add(ChildComponent); } } 在这里我可以动态添加ChildComponents,但是如何设置其文本? 编辑: 我不知道是否对其他人有用,但为ChildComponent定义一个参数类,并将ContainerComponent的elements数组更新为包含特定args的对象数组,我可以轻松地将特定参数传递给ChildComponents: container.component.ts import { Component,ComponentFactory } from '@angular/core'; export class ChildArgs { type: Type; args: any; } @Component({ selector: 'wrapper-component',OnDestroy { @Input() argsElement: ChildArgs; @ViewChild('container',{read: ViewContainerRef}) container; cmpRef: ComponentRef<any>; private isViewInitialized: boolean = false; constructor(private resolver: ComponentResolver) { } private updateComponent() { if(!this.isViewInitialized) return; if(this.cmpRef) this.cmpRef.destroy(); this.resolver.resolveComponent(this.argsElement.type).then((factory: ComponentFactory<any>) => { this.cmpRef = this.container.createComponent(factory); this.cmpRef.instance.args = this.argsElement.args; }) } ngOnChanges() { this.updateComponent(); } ngAfterViewInit() { this.isViewInitialized = true; this.updateComponent(); } ngOnDestroy() { if(this.cmpRef) this.cmpRef.destroy(); } } @Component({ selector: 'container-component',template: ` <wrapper-component *ngFor="let argsElement of argsElements" [argsElement]="argsElement"> </wrapper-component> `,directives: [WrapperComponent] }) export class ContainerComponent { private argsElements: ChildArgs[] = []; AddArgsElement(argsElement: ChildArgs) { this.argsElements.push(argsElement); } } a1.component.ts import { Component,ViewChild } from '@angular/core' import { ContainerComponent,ChildArgs } from '../../components/container.component'; class ChildComponentArgs { text: string; } @Component({ selector: 'child-component',template: '<div>a{{args.text}}</div>' }) class ChildComponent { args: ChildComponentArgs; } class ChildComponent2Args { text: string; } @Component({ selector: 'child-component2',template: '<div>b{{args.text}}</div>' }) class ChildComponent2 { args: ChildComponent2Args; } @Component({ selector: 'a1step',template: ` <button (click)="onClick()">Add</button> <button (click)="onClick2()">Add2</button> <container-component #container></container-component> `,directives: [ContainerComponent] }) export class A1Step { @ViewChild('container') container : ContainerComponent; private cnt: number = 0; private cnt2: number = 0; onClick() { let childComponentArgs: ChildComponentArgs = new ChildComponentArgs(); childComponentArgs.text = "" + ++this.cnt; let childArgs: ChildArgs = new ChildArgs(); childArgs.type = ChildComponent; childArgs.args = childComponentArgs; this.container.AddArgsElement(childArgs); } onClick2() { let childComponentArgs: ChildComponent2Args = new ChildComponent2Args(); childComponentArgs.text = "" + ++this.cnt2; let childArgs: ChildArgs = new ChildArgs(); childArgs.type = ChildComponent2; childArgs.args = childComponentArgs; this.container.AddArgsElement(childArgs); } } 解决方法
您可以使用cmpRef.instance访问创建的组件实例:
this.resolver.resolveComponent(this.type).then((factory: ComponentFactory<any>) => { this.cmpRef = this.container.createComponent(factory); this.cmpRef.instance.text = this.someText; }) 有关完整示例,另请参见Angular 2 dynamic tabs with user-click chosen components. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |