Angular 2在不使用ViewContainerRef的情况下将组件动态插入特定的DOM节点 [英] Angular 2 Dynamically insert a component into a specific DOM node without using ViewContainerRef

查看:73
本文介绍了Angular 2在不使用ViewContainerRef的情况下将组件动态插入特定的DOM节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于在Angular 2 rc5中创建动态组件的问题.

I have a question regarding dynamic component creation in Angular 2 rc5.

因此,我们假设我们有两个简单的角度分量:

So let's assume that we have two plain angular components:

  @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!' }

然后,某些外部非角度代码块将修改DOM:

Then some external non-angular chunck of code modificates a DOM:

let newNode = document.createElement('div');
newNode.id = 'placeholder';
document.getElementById('container').appendChild(newNode);

以下是经过处理的一些可能的树:

Here is some presumable tree after manipulations:

 <div id="container">
      <h1>My Component</h1>
      <div id="placeholder"></div>
 </div>

所以我想做的就是将SimpleComoponent实例动态添加到#placeholder div中.我怎样才能达到这个结果?

So what I'm trying to do is just dynamically add SimpleComoponent instance into #placeholder div. How can I achieve this result?

我一直在尝试使用ComponentFactory.createComponent(injector,[],newNode),尽管它添加了组件,但是生命周期钩子和绑定都没有用.

I've been trying using ComponentFactory.createComponent(injector, [], newNode), it added the component though, but neither life cycle hooks nor binding not worked at all.

我相信可以使用ViewContainerRef来实现此目的,但是如何将其与动态创建的节点链接起来呢?

I believe there is some way to implement this using ViewContainerRef, but how can I link it with dynamically created node?

这是我期望的结果

 <div id="container">
      <h1>My Component</h1>
      <div id="placeholder">
        <simple-cmp>Hello world!</simple-cmp>
      </div>
 </div>

谢谢!

推荐答案

在创建组件时您可以传递将用作所创建组件的宿主元素的DOM节点:

When creating a component you can pass the DOM node that will act as a host element of the created component:

create(injector:Injector,projectableNodes ?: any [] [], rootSelectorOrNode ?: string | any ,ngModule ?: NgModuleRef): ComponentRef

create(injector: Injector, projectableNodes?: any[][], rootSelectorOrNode?: string|any, ngModule?: NgModuleRef): ComponentRef

但是由于此组件不是任何其他组件的子组件,因此必须手动将其附加到ApplicationRef上,以便进行更改检测.

But since this component is not child of any other component, you have to manually attach it to ApplicationRef so you get change detection.

这就是您需要做的:

1)创建一个组件,指定要在其下添加根节点的组件.
2)将视图附加到ApplicationRef,以便进行更改检测.您仍然没有InputngOnChanges操作,但是DOM更新将正常工作.

1) Create a component specifying the root node under which it should be added.
2) Attach the view to the ApplicationRef so that you get change detection. You will still have no Input and ngOnChanges operations, but the DOM update will be working fine.

  @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);
      }
  }

这篇关于Angular 2在不使用ViewContainerRef的情况下将组件动态插入特定的DOM节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆