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

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

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

  • OptionsMenuComponent(一个菜单)
  • 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。没有它,当我加载页面时,我会收到以下错误:

Error: Uncaught (in promise): Unexpected directive value 'undefined' on the View of component 'MenuItemComponent'

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

[gulp-tslint] error (no-forward-ref) menu-item.component.ts[9, 18]: Avoid using forwardRef in class "MenuItemComponent"

我在网上四处寻找替代解决方案,但一无所获。我只能找到两个建议:

  • 我对 forwardRef 的解决方案
  • “你有一个循环引用,你做错了什么所以将它们解耦”(不是确切的词)

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

第二个建议在大多数情况下都是正确且易于实现的,但我如何在递归结构(使用 angular2 组件)中做到这一点?

谢谢,

p.s - 在此之前,我在一个组件中拥有所有功能,而且我对引用自身的单个组件没有任何问题(不需要 forwardRef)所以请不要推荐这样做因为这里不是这种情况(尽量保持组件小而简单)

长话短说:
两个组件相互引用(需要递归结构)。 如果不使用 forwardRef,我会收到错误消息,是否有不涉及使用 forwardRef 的替代解决方案?

最佳答案

这是我编写的递归导航示例,已简化为有序列表。简而言之,您正在定义一个模板来递归,然后迭代根子级(页面集合)context:{ $implicit: root.children },并在每个子级上迭代根通过更改上下文 context:{ $implicit: page.children } 来生成 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>

关于typescript - 使用 angular2 组件(没有 forwardRef)实现递归结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38612329/

相关文章:

typescript - 类型不可分配给类型 2322

javascript - 使用 rxjs 时,为什么 switchMap 不触发 complete 事件?

angular - ngIf 导致错误 : Conditional Expression requires all 3 expressions at the end of expression

javascript - 操作 Angular 2 中 HTML 元素的位置

angular - 如何删除 Dart Angular2 教程中的 "property binding not used by any directive"错误?

node.js - 要求 ts-node 和 ts-node/register 有什么区别

node.js - 在 Typescript Node+Express 项目中使用模块中的 TypeScript 文件的正确方法?当前抛出错误 : Cannot find module

javascript - Typescript ReconnectingWebSocket 无法调用构造函数

javascript - Angular 将 URL 中的 "/"替换为 "%2F"

angular - 没有 TemplateRef 的提供者! (NgIf ->TemplateRef)