获取递归嵌套模板调用以在Angular 2中工作?

时间:2016-04-01 09:05:04

标签: html templates typescript angular angular-directive

我希望这个标题不会误导太多,因为我不知道怎么称呼它,但这就是问题所在:

我正在使用Angular 2开发一个应用程序,并在几个实例中使用嵌套模板(希望它们是正确的名称)。 现在我的问题是我的应用程序包含几个"小部件"其中可以包含其他小部件。这可以在模板调用中创建一种圆圈。

示例:

home.html的:

<div> some html stuff </div>
<widget1 *ng-for="#widget of widgetList" [widget]="widget"></widget1>

widget1.html:

<div> some html stuff unique to widget1 </div>
<div *ng-if="widget.widgetSubList">
  <div *ng-for="#widget of widget.widgetSubList">
    <div [ng-switch]="widget.type">
      <p *ng-switch-when="2"><widget2 [widget]="widget"></></widget2></p>
      <p *ng-switch-when="3"><widget3 [widget]="widget"></></widget3></p>
    </div>
  </div>
</div>

widget2.html

<div> some html stuff unique to widget2 </div>
<div *ng-if="widget.widgetSubList">
  <div *ng-for="#widget of widget.widgetSubList">
    <div [ng-switch]="widget.type">
      <p *ng-switch-when="1"><widget1 [widget]="widget"></></widget1></p>
      <p *ng-switch-when="3"><widget3 [widget]="widget"></></widget3></p>
    </div>
  </div>
</div>

widgetSubList是窗口小部件的一个属性,如果它有子窗口小部件,则填充它,ng-if在这种情况下有效,如果没有子窗口小部件,则不会使代码崩溃。

这就是整个事情崩溃的关键所在,因为它创造了所提到的&#34;圈&#34;包含小部件的小部件已经在树的上面部分,因为widget1可以调用widget2,它可以再次调用widget1。 我无法改变这种结构,因为它是我在这种情况下使用的API预先确定的。

现在问题是:有没有办法让这项工作?

由于所有小部件都需要不同的实现,我无法在不创建一个填充了ng-ifs的巨型html文件的情况下解决它,我想避免这种情况。

PS:我进一步编辑了这个例子,以更好地表示代码。 @Input部分出现在.ts文件中。

目前,我只是从API中读出了一个额外级别的子窗口小部件用于测试目的。

1 个答案:

答案 0 :(得分:0)

有点奇怪的是,widget1.htmlwidget2.html文件中没有小部件循环。使用您的工具,您始终保持相同的窗口小部件元数据,因此您有一个无限循环是正常的...

事实上,你需要一个允许定义组件结构的递归结构:

widgetList
  widget
    children
      widget
        children
      widget
        children
  widget
    children
      widget
        children
  (...)

因此,当前小部件没有子节点时,递归循环将结束。

所以我会像这样重构你的模板(例如widget1.html):

<div> some html stuff unique to widget1 </div>
<div *ng-for="#subWidget of widget.children">
  <div [ng-switch]="subWidget.type">
    <p *ng-switch-when="2"><widget2 [widget]="subWidget"></widget2></p>
    <p *ng-switch-when="3"><widget3 [widget]="subWidget"></widget3</p>
  </div>
</div>

每个小部件都有一个与小部件元数据相对应的输入:

@Component({
  selector: 'widget1',
  (...)
})
export class Widget1Component {
  @Input()
  widget: any;
}