简体   繁体   English

ngFor中的动态组件

[英]Dynamic components inside ngFor

I am converting an angular 1 application to angular 2. I have the dynamic directives working in angular 1 in a ng-repeat. 我正在将角度1应用程序转换为角度2.我有动态指令在ng-repeat中以角度1工作。 I went off of this plunker http://plnkr.co/edit/ET3LZhXBRjwIsbKVIwxm?p=preview 我离开了这个傻瓜http://plnkr.co/edit/ET3LZhXBRjwIsbKVIwxm?p=preview

<tr ng-repeat="p in people">
     <td dynamic-directive="p.dir" blah="p"></td>
</tr>

from this question : Angularjs dynamic directive inside ngrepeat 来自这个问题: ngrepeat中的Angularjs动态指令

Is it possible to do the basically the same thing with angular 2? 是否可以使用角度2进行基本相同的操作? My data model will tell me what component to use and what data to pass in to the component. 我的数据模型将告诉我使用什么组件以及传递给组件的数据。

Edit: So my use case is: My main page on my site can have 10 different widgets and each widget is a different component - currently a directive in angular 1. Each component needs different data. 编辑:所以我的用例是:我的网站上的主页面可以有10个不同的小部件,每个小部件是一个不同的组件 - 目前是角度1的指令。每个组件需要不同的数据。 The components can be in any order depending on how the site admin adds them in the database. 组件可以按任何顺序排列,具体取决于站点管理员在数据库中添加它们的方式。 I get the data from an API. 我从API获取数据。 In the data structure, there is a one to many: component > data. 在数据结构中,有一对多:component> data。 I need to loop through the data and add the components dynamically based on the component name from the data set. 我需要遍历数据并根据数据集中的组件名称动态添加组件。 The data structure looks something like this. 数据结构看起来像这样。

"Topics":[
         {
            "component":"header",
            "Slug":"fake-slug",
            "URL":"some-image"
         },
         {
            "component":"standardcontent",
            "Slug":"fake-slug",
            "URL":"some-image"
         },
         {
            "component":"playlist",
            "PlayLists":[
               {
                  "CONPlaylistID":"22",
                  "description":"fake-description",
                  "image":"fake-image"
               },
               {
                 "CONPlaylistID":"22",
                  "description":"fake-description",
                  "image":"fake-image"
               }
            ]
         }
   ]

Thanks in advance 提前致谢

Directives can only be added by static HTML that matches the directive selector and there is no other mechanism to depend directive instantiation on. 指令只能通过与指令选择器匹配的静态HTML添加,并且没有其他机制可以依赖指令实例化。

You can use two similar elements where one matches the directive selector and the other doesn't and switch between them: 您可以使用两个类似的元素,其中一个匹配指令选择器而另一个不匹配,并在它们之间切换:

<tr *ngFor="let p of people">
  <td *ngIf="doAddDirective" dynamic-directive="p.dir" blah="p"></td>
  <td *ngIf="!doAddDirective" blah="p"></td>
</tr>

If it's about components instead of directives this might be what you want Angular 2 dynamic tabs with user-click chosen components 如果它是关于组件而不是指令,那么您可能希望使用用户单击所选组件的Angular 2动态选项卡

update Some explanation what <dcl-wrapper> does: 更新 <dcl-wrapper>一些解释:

There are two main things, the rest is only to wrap it in a component for easier reuse. 有两个主要的东西,其余的只是将它包装在一个组件中以便于重用。

The first is the ViewContainerRef and how to get it. 第一个是ViewContainerRef以及如何获取它。 This defines where the dynamically component will be added. 这定义了动态组件的添加位置。 You can either inject ViewContainerRef then the dynamically component will be added below (not inside) the current component 您可以注入ViewContainerRef然后将动态组件添加到当前组件的下方(而不是内部)
or you can acquire it from an element in the template of the current component using @ViewChild(..., {read: ViewContainerRef}) , then the dynamically added element will be inserted below that element. 或者您可以使用@ViewChild(..., {read: ViewContainerRef})从当前组件的模板中的元素获取它,然后将动态添加的元素插入该元素下面。

The 2nd part is resolveComponent() with target.createComponent() that is the code that actually inserts the dynamic component. 第二部分是使用target.createComponent() resolveComponent() ,它是实际插入动态组件的代码。

The dcl-wrapper component is to make it easy to declaratively add dynamic components. dcl-wrapper组件使声明性地添加动态组件变得容易。 Just add 只需添加

<dcl-wrapper [type]="item.type"></dcl-wrapper>

to your template (assuming item is from *ngFor referring to an item of your JSON). 到您的模板(假设item来自*ngFor表示您的JSON项目)。

This will add a <dcl-wrapper></dcl-wrapper> component to your component and the <dcl-wrapper> will then add the dynamic component returned by item.type inside itself. 这将向组件添加<dcl-wrapper></dcl-wrapper>组件,然后<dcl-wrapper>将添加由item.type返回的动态组件。 The other code in <dcl-wrapper> is for when item.type changes to remove the previously added dynamic component and add the one item.type now refers to. <dcl-wrapper>的其他代码用于当item.type更改时删除以前添加的动态组件并添加一个item.type现在引用。

hint The dynamic component item.type needs to be a type reference not a string name. 提示动态组件item.type必须是类型引用而不是字符串名称。 Therefore you need a way to get the component type from the name. 因此,您需要一种从名称中获取组件类型的方法。 You could provide a global service that returns the type from the name. 您可以提供从名称返回类型的全局服务。 You would need to maintain the mapping manually. 您需要手动维护映射。 There are ways to get the type from a name string imperatively in TypeScript but I haven't found the SO question/answer where this is explained. 有一些方法可以在TypeScript中命令性地从名称字符串中获取类型,但是我没有找到解释这个问题的答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM