【问题标题】:How to load dynamically a component in angular 4 in the parent component如何在父组件中以角度 4 动态加载组件
【发布时间】:2017-10-05 15:59:09
【问题描述】:

我正在创建要加载到父组件中的模板组件,具体取决于我从服务器获得的响应。我会给你一个简短的例子,说明我正在尝试用伪代码做什么。

这是我的 html 父组件:

<div class="parent-container">
    <div *ngIf="template1"> (load template1.component) </div>
    <div *ngIf="template2"> (load template2.component) </div>
    etc...
</div>

那么我将拥有不同的组件(为简洁起见,我只列出一个)

<div class="child-container">
    <div> {{userName}} </div>
    <div> {{contactNo}} </div>
    <div> {{address}} </div>
</div>

在 ngInit 上,父级向服务器发出一个 http 请求并获取一个值。取决于父项中的值,我应该能够将子模板加载到父项中并显示它。因此,一旦加载,页面将如下所示:

<div class="parent-container">
    <div class="child-container">
        <div> {{userName}} </div>
        <div> {{contactNo}} </div>
        <div> {{address}} </div>
    </div>
</div>

有角度的可能吗?我怎样才能创建它? 谢谢

[编辑]

我实现了dee zg的建议,代码如下:

@ViewChild(HostDirective) host: HostDirective;

OnNgInit(){}

//switch will be a response from a server 
selector(switch){
    switch(switch) { 
       case 'component1': { 
         this.loadComponent(Component1);
         break; 
      }  
      default: { 

         break; 
      } 
   } 

  }

  loadComponent(component){   


    var componentFactory = this._componentFactoryResolver.resolveComponentFactory(component);
    var viewContainerRef = this.host;
    this.viewContainerRef.clear();
    var componentRef = this.viewContainerRef.createComponent(componentFactory);

    (componentRef.instance);

  }

这就是我的主机里面的东西

import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[host]',
})
export class HostDirective {
  constructor(public viewContainerRef: ViewContainerRef) { }
}

和 html

<ng-template host></ng-template>

有趣的是,如果 loadComponent 中的任何内容都将被加载到 OnInit 中,那么它将起作用。如果我从 loadComponent 调用它,我将得到该主机未定义。

【问题讨论】:

  • 您知道哪些是您可以实际加载的组件吗?因为如果是这样,那么您当前的方法有效。这不是最优雅的方法,但它有效
  • 是的,但我想要一个 if 语句,我将在其中加载后端告诉我的任何组件。父组件会根据响应选择使用哪个模板组件,然后将信息解析到 html 并渲染组件
  • 编辑:查看 dee zg 答案。好的,有一种方法可以使用ViewContainerRefComponentFactoryResolver ng-template 标签内动态加载组件,但是您仍然需要在父组件装饰器中“声明”您的动态组件,给我一些时间,我可以设置给你一个笨拙的人
  • 是什么触发了您的selector(switch)
  • 基本上是来自服务器的响应。所以我向它发出一个http请求,如果我发现响应的属性为“Component1”,那么它将去切换,其余的也是如此。为简洁起见,我省略了所有其他内容,但一遍又一遍是同一件事

标签: angular


【解决方案1】:

在模板中:

<ng-template #yourComponentHost></ng-template>

在组件中:

@ViewChild('yourComponentHost', { read: ViewContainerRef })
  yourComponentHost;
.
.
.
const componentFactory = this._componentFactoryResolver.resolveComponentFactory(YourComponentType1);
    const viewContainerRef = this.yourComponentHost;
    viewContainerRef.clear();
    const componentRef = viewContainerRef.createComponent(componentFactory);

    const yourComponentType1Instance = (<YourComponentType1>componentRef.instance);

从这里,您可以通过yourComponentType1Instance 访问您的组件。当然,你会在resolveComponentFactory中做你自己的切换逻辑,根据你想要的条件使用你需要的组件。

【讨论】:

  • 我遇到了这段代码的问题:(componentRef.instance); ,我希望它是动态的。我正在通过一个方法解析组件(所以基本上我将解析 YourComponentType1 或 2 或 3),但是如果我以这种方式解析它,我会收到一条错误消息:错误:没有为 [object Object] 找到组件工厂。你把它添加到@NgModule.entryComponents 了吗?知道如何解决吗?
  • 哦,是的,绝对!使用componentFactory 创建的组件必须添加到entryComponentsangular.io/guide/dynamic-component-loader#resolving-components。否则,Angular 将不知道 YourComponentType1 实际上是什么。
  • 我做了,但结果相同。调试我发现每当我解析 yourcomponent1 时,它都是一个对象(如果我在 ngInit 上执行它,它将被解析为一个组件)。所以我解析 yourcomponent1.constructor 来启动组件。接下来发生的是 this.yourComponentHost 未定义
  • hm...让我问一下,只是为了确定,'parse yourcomponent1 到底是什么意思?
  • 如果您正在讨论要通过字符串实例化的组件之间的切换,那么这可能很有用:stackoverflow.com/questions/40062970/…
【解决方案2】:

您要查找的内容有点令人困惑。因为你的问题,为什么不为你的孩子创建组件。

<div class="parent-container">
    <div *ngIf="template1"> <template1 [myData]="myData"></template1> </div>
    <div *ngIf="template2"> <template2 [myData]="myData"></template2> </div>
    etc...
</div>

【讨论】:

    猜你喜欢
    • 2018-08-11
    • 2018-08-25
    • 2017-07-19
    • 2019-07-11
    • 2022-01-04
    • 2017-10-10
    • 1970-01-01
    • 2018-05-29
    • 1970-01-01
    相关资源
    最近更新 更多