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

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

问题描述

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

所以让我们假设我们有两个普通的角度分量:

 @Component({模板:`<div id="容器"><h1>我的组件</h1>

`,选择器:'我的应用'})导出类 AppComponent { }@成分({模板:'<p>{{text}}</p>',选择器:'简单的cmp'})导出类 SimpleComponent { public text='Hello World!'}

然后一些外部非角度代码修改了 DOM:

let newNode = document.createElement('div');newNode.id = '占位符';document.getElementById('container').appendChild(newNode);

这是一些经过操作后的推定树:

 

<h1>我的组件</h1><div id="placeholder"></div>

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

我一直在尝试使用 ComponentFactory.createComponent(injector, [], newNode),虽然它添加了组件,但生命周期钩子和绑定都不起作用.

我相信有一些方法可以使用 ViewContainerRef 来实现这一点,但是如何将它与动态创建的节点链接起来?

这是我期望的结果

 

<h1>我的组件</h1><div id="占位符"><simple-cmp>你好世界!</simple-cmp>

谢谢!

解决方案

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

<块引用>

create(injector: Injector, projectableNodes?: any[][],rootSelectorOrNode?: string|any, ngModule?: NgModuleRef):组件引用

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

所以这是你需要做的:

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

 @Component({模板:`<div id="容器"><h1>我的组件</h1>

`,选择器:'我的应用'})导出类 AppComponent {构造函数(私有解析器:ComponentFactoryResolver,私人注射器:注射器,私人应用程序:ApplicationRef) {}添加动态组件(){让工厂 = this.resolver.resolveComponentFactory(SimpleComponent);让 newNode = document.createElement('div');newNode.id = '占位符';document.getElementById('container').appendChild(newNode);const ref = factory.create(this.injector, [], newNode);this.app.attachView(ref.hostView);}}

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

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>

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

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.

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

Here is the result I expect

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

Thanks!

解决方案

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

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

So here is what you need to do:

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天全站免登陆