使用angular2组件实现递归结构(没有forwardRef)?

时间:2016-07-27 11:59:16

标签: typescript angular angular2-template angular2-directives forward-reference

我有一个递归结构,由两个组成部分组成:

  • OptionsMenuComponent(A菜单)
  • MenuItemComponent(菜单项)

OptionsMenuComponent:(模板+组件)

Template:
    <menu-item *ngFor="let menuItem of menu.menuItems" [menuItem]="menuItem"> </menu-item>

Component:
    import { Component, Input } from '@angular/core';
    import { Menu } from '../models/menu.model';
    import { MenuItemComponent } from '../menu-item/menu-item.component';

    @Component({
        moduleId: __moduleName,
        selector: 'options-menu',
        templateUrl: 'options-menu.component.html',
        styleUrls: ['options-menu.component.css'],
        directives: [MenuItemComponent],
    })
    export class OptionsMenuComponent {
        @Input() menu: Menu;

        constructor() { }
    }

菜单项:(模板+组件)

Template:
    <span class="menu-item-title">{{menuItem.title}}</span>

    <options-menu *ngIf="menuItem.subMenu != null" [menu]="menuItem.subMenu" class="sub-menu"> </options-menu>

Component:
    import { Component, Input, forwardRef } from '@angular/core';
    import { MenuItem } from '../models/menu-item.model';
    import { OptionsMenuComponent } from '../options-menu/options-menu.component';

    @Component({
        moduleId: __moduleName,
        selector: 'menu-item',
        directives: [forwardRef(() => OptionsMenuComponent)],
        templateUrl: 'menu-item.component.html',
        styleUrls: ['menu-item.component.css'],
    })
    export class MenuItemComponent {
        @Input() menuItem: MenuItem;

        constructor() { }

    }

注意:我删除了几乎所有逻辑和设计以简化,因为它不相关

正如您所看到的,OptionsMenuComponent知道MenuItemComponent,反之亦然 另外你可能已经注意到在MenuItemComponent中我在指令中使用了forwardRef。加载页面时没有这个,我得到以下错误:

  

错误:未捕获(在承诺中):意外的指令值&#39;未定义&#39;   在组件的视图&#39; MenuItemComponent&#39;

目前它的编写方式(使用forwardRef)效果很好,但TSLint对此不满意并输出以下内容:

  

[gulp-tslint] error(no-forward-ref)menu-item.component.ts [9,18]:   避免在类&#34; MenuItemComponent&#34;

中使用forwardRef

我环顾网络寻找其他解决方案并空手而归。我能找到的只有两个建议:

  • 我使用forwardRef的解决方案
  • &#34;你有一个循环引用,你做错了什么,所以解耦他们&#34; (不是确切的词)

第一个建议有效,但我的问题是,是否可以避免这种情况,因为它听起来并不是一种好的做法(而且人们都说要避免这种做法)

对于大多数情况,第二个建议是正确且易于实现的,但我如何在递归结构中执行此操作(使用angular2组件)?

非常感谢,

ps - 在此之前,我拥有一个组件中的所有功能,并且我没有对引用自身的单个组件(不需要forwardRef)有任何问题,所以请不要这样做。建议这样做,因为这不是这种情况(试图保持组件小而简单)

TL; DR:
两个组件相互引用(需要递归结构)。 不使用forwardRef我得到错误,是否有替代解决方案不涉及使用forwardRef?

1 个答案:

答案 0 :(得分:0)

这是我写的递归导航的一个例子,剥离到有序列表。简而言之,您要定义一个递归模板,然后遍历根子项(页面集合)context:{ $implicit: root.children },并在每个子项上,通过更改上下文context:{ $implicit: page.children }来迭代根子项。

<ng-template #nav let-pages>
  <ol>
    <ng-container *ngFor="let page of pages">
      <ng-container *ngIf="page.public && page.visible">
        <li>
          <a routerLink="/{{page.urlname}}">{{page.name}}</a>
          <ng-container *ngTemplateOutlet="nav; context:{ $implicit: page.children }"></ng-container>
        </li>
      </ng-container>
    </ng-container>
  </ol>
</ng-template>
<ng-container *ngTemplateOutlet="nav; context:{ $implicit: root.children }"></ng-container>