Val*_*dov 11 typescript angular2-template angular
我有一个关于Angular 2 rc5中动态组件创建的问题.
所以我们假设我们有两个普通的角度分量:
@Component({
template: `
<div id="container">
<h1>My Component</h1>
</div>
`,
selector: 'my-app'
})
export class AppComponent { }
@Component({
template: '<p>{{text}}</p>',
selector: 'simple-cmp'
})
export class SimpleComponent { public text='Hello World!' }
Run Code Online (Sandbox Code Playgroud)
然后一些外部非角度代码块修改DOM:
let newNode = document.createElement('div');
newNode.id = 'placeholder';
document.getElementById('container').appendChild(newNode);
Run Code Online (Sandbox Code Playgroud)
这是操作后的一些可能的树:
<div id="container">
<h1>My Component</h1>
<div id="placeholder"></div>
</div>
Run Code Online (Sandbox Code Playgroud)
所以我要做的就是将SimpleComoponent实例动态添加到#placeholder div中.我怎样才能达到这个效果?
我一直在尝试使用ComponentFactory.createComponent(injector,[],newNode),但它添加了组件,但生命周期挂钩和绑定都没有工作.
我相信有一些方法可以使用ViewContainerRef来实现它,但是如何将它与动态创建的节点链接?
这是我期望的结果
<div id="container">
<h1>My Component</h1>
<div id="placeholder">
<simple-cmp>Hello world!</simple-cmp>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
谢谢!
Max*_*kyi 18
创建组件时,您可以传递将充当所创建组件的主机元素的DOM节点:
create(injector:Injector,projectableNodes?:any [] [], rootSelectorOrNode?:string | any,ngModule?:NgModuleRef):ComponentRef
但由于此组件不是任何其他组件的子组件,因此必须手动将其附加到ApplicationRef,以便进行更改检测.
所以这就是你需要做的:
1)创建一个组件,指定应添加它的根节点.
2)将视图附加到ApplicationRef,以便进行更改检测.你仍然没有Input和ngOnChanges操作,但DOM更新将正常工作.
@Component({
template: `
<div id="container">
<h1>My Component</h1>
</div>
`,
selector: 'my-app'
})
export class AppComponent {
constructor(private resolver: ComponentFactoryResolver,
private injector: Injector,
private app: ApplicationRef) {
}
addDynamicComponent() {
let factory = this.resolver.resolveComponentFactory(SimpleComponent);
let newNode = document.createElement('div');
newNode.id = 'placeholder';
document.getElementById('container').appendChild(newNode);
const ref = factory.create(this.injector, [], newNode);
this.app.attachView(ref.hostView);
}
}
Run Code Online (Sandbox Code Playgroud)
你永远不应该在Angular之外修改DOM,因为它会导致不可预测的行为.即使你<simple-cmp>手动附加元素,它也没有任何意义,因为它不是由Angular处理的.Angular app中对DOM的所有更改都必须通过Angular方法.
动态创建一个新组件:
@Component({
selector: 'my-component',
template: '<div #element></div>',
})
export class MyComponent {
@ViewChild('element', {read: ViewContainerRef}) private anchor: ViewContainerRef;
constructor(private resolver: ComponentFactoryResolver) { }
whatever() {
let factory = this.resolver.resolveComponentFactory(ChildComponent);
this.anchor.createComponent(factory);
}
}
Run Code Online (Sandbox Code Playgroud)