我想创建动态组件并将这些组件的视图插入到容器中。
我认为这可以通过ViewContainerRef实现。
但我不知道,我们可以获得ViewContainerRef
任何组件吗?如果是的话怎么样?
我是Angular的新手,如果有任何其他好的解决方案可以处理这种情况,请建议我。
更新 我想,我非常接近解决方案。以下是代码。
app.component.ts
import {Component} from '@angular/core';
import {ContainerComponet} from './container.component'
@Component({
selector: 'my-app',
template: `
<container> </container>
`,
directives: [ContainerComponet]
})
export class AppComponent {
constructor() { }
}
container.component.ts
import {Component, ComponentResolver, ViewContainerRef} from '@angular/core'
import {controlBoxComponent as controlBox} from './controlBox.component';
@Component({
selector: 'container',
template: 'container'
})
export class ContainerComponet {
constructor(viewContainer: ViewContainerRef, private _cr: ComponentResolver) {
this._cr.resolveComponent(controlBox)
.then(cmpFactory => {
const ctxInjector = viewContainer.injector;
return viewContainer.createComponent(cmpFactory, 0, ctxInjector);
})
}
}
controlBox.component.ts
import {Component} from '@angular/core'
@Component({
selector: 'controlBox',
template: 'controlBox'
})
export class controlBoxComponent {
constructor() { }
}
输出
<my-app>
<container>container</container><controlbox _ngcontent-lsn-3="">controlBox</controlbox>
</my-app>
预期结果
<my-app>
<container>container
<controlbox _ngcontent-lsn-3="">controlBox</controlbox>
</container>
</my-app>
答案 0 :(得分:49)
您可以通过当前组件视图中的元素获取当前组件的ViewContainerRef
@Component({
selector: '...',
directives: [OtherComponent, FooComponent],
template: `
<other-component></other-component>
<foo-component #foo></foo-component>
<div #div></div>`
})
export class SomeComponent {
// `ViewContainerRef` from an element in the view
@ViewChild(OtherComponent, {read: ViewContainerRef}) other;
@ViewChild('foo', {read: ViewContainerRef}) foo;
@ViewChild('div', {read: ViewContainerRef}) div;
// `ViewContainerRef` from the component itself
constructor(private viewContainerRef:ViewContainerRef, private componentFactoryResolver: ComponentFactoryResolver) {}
let factory = this.componentFactoryResolver.resolveComponentFactory(ControlBox)
this.componentRef = this.other.createComponent(factory);
// this.componentRef = this.foo.createComponent(factory);
// this.componentRef = this.div.createComponent(factory);
// this.componentRef = this.viewContainerRef.createComponent(factory);
});
}
答案 1 :(得分:0)
我为我的应用做了类似的事情。在表格中加载数据。
为此,我创建了一个指令:
directives: [TableDirective]
然后我就这样使用它:
@ViewChild(TableDirective) tableDirective:TableDirective;
ngAfterViewInit() {
setTimeout(_=>this.load());
}
load() {
this.tableDirective.loadTable(*ADirectiveToLoad*);
}
TableDirective文件:
import { Component, DynamicComponentLoader, ViewContainerRef } from 'angular2/core';
@Component({
selector: "my-table",
template: `<my-data></my-data>`
})
export class TableDirective {
constructor(
private dcl:DynamicComponentLoader,
private viewContainerRef:ViewContainerRef) {
}
public loadTable(base:any) {
this.viewContainerRef.clear();
this.dcl.loadNextToLocation(base, this.viewContainerRef);
}
}
这将在我的表中加载数据,取决于我发送的指令。 例如:
import { Component, OnInit } from 'angular2/core';
@Component({
selector: "my-data",
templateUrl: "app/_includes/table/actionnaire/table.html"
})
export class ActionnaireDirective implements OnInit {
private entity:any;
ngOnInit() {
this.entity = ACTIONNAIRES_PORTEUR;
}
}
var ACTIONNAIRES_PORTEUR:Actionnaire[] = [
{"id": 1, "nom": "Test", "prenom": "Testeur", "dateNaissance": "15/05/1995"}
];
export class Actionnaire {
id:number;
nom:string;
prenom:string;
dateNaissance:any;
}
我也是Angular的新手:x
答案 2 :(得分:0)
我也在寻找这个问题的解决方案。
我能够实现这一目标的唯一方法是使用额外的Component
import {Component, ViewContainerRef} from '@angular/core';
@Component({
selector: 'sw-view-container-ref',
template: `<div></div>`
})
export class SwViewContainerRef {
private _viewContainerRef:ViewContainerRef;
constructor(viewContainerRef:ViewContainerRef) {
this._viewContainerRef = viewContainerRef;
}
get viewContainerRef():ViewContainerRef {
return this._viewContainerRef;
}
}
container.component.ts
import {Component, ComponentResolver, ViewContainerRef, AfterViewInit, ViewChild,Injector} from '@angular/core'
import {controlBoxComponent as controlBox} from './controlBox.component';
import {SwViewContainerRef} from "./sw-view-container-ref";
@Component({
selector: 'container',
template: 'container<sw-view-container-ref #swViewContainerRef></sw-view-container-ref>',
directives: [SwViewContainerRef]
})
export class ContainerComponet implements AfterViewInit {
@ViewChild('swViewContainerRef', SwViewContainerRef) swViewChild:SwViewContainerRef;
ngAfterViewInit() {
this.desiredViewContainerRef = this.swViewChild.viewContainerRef;
var self = this;
this._cr.resolveComponent(controlBox).then((factory) => {
var componentRef = self.desiredViewContainerRef.createComponent(factory, null, self.injector, null);
componentRef.changeDetectorRef.detectChanges();
componentRef.onDestroy(()=> {
componentRef.changeDetectorRef.detach();
})
return componentRef;
});
}
public desiredViewContainerRef:ViewContainerRef;
constructor(private _cr: ComponentResolver, public injector:Injector) {
}
}
它应该产生类似的东西。
<my-app>
<container>container
<sw-view-container-ref><div></div></sw-view-container-ref>
<controlbox>controlBox</controlbox>
</container>
</my-app>
我不确定我的示例是否清晰或有效,随时提出问题或提出建议,我会尝试回答并更新我的示例。