以递归方式使用组件来创建树

Ser*_*hiy 28 components angular

你知道可以自己使用组件吗?如果是的话,在哪里阅读它?

我有下一个情况:有mainItems列表,每个Main Item都有subItem(看起来像mainItem),每个subItem都可以拥有它自己的subItem等.所以最好使用嵌套,但是如何?

Gün*_*uer 36

更新

forwardRef()不再需要因为directives被移动NgModule.declarations,因此递归组件不再需要自己注册directives.

Angular 4.xx Plunker示例

原版的

支持.您只需要directives: []在其@Component()装饰器中添加组件即可.因为装饰器在类之前,并且在声明它们之前无法引用类forwardRef()是必要的.

import {Component, forwardRef, Input} from '@angular/core'

@Component({
  selector: 'tree-node',
  template: `
  <div>{{node.name}}</div>
  <ul>
    <li *ngFor="let node of node.children">
      <tree-node  [node]="node"></tree-node>
    </li>
  </ul>
`
})
export class TreeNode {
  @Input() node;
}
Run Code Online (Sandbox Code Playgroud)
@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <tree-node [node]="node"></tree-node>
    </div>
  `,
  directives: [TreeNode]
})
export class App {
  constructor() {
    this.name = 'Angular2 (Release Candidate!)'
  }

  node = {name: 'root', children: [
    {name: 'a', children: []},
    {name: 'b', children: []},
    {name: 'c', children: [
      {name: 'd', children: []},
      {name: 'e', children: []},
      {name: 'f', children: []},
     ]},
  ]};  
}
Run Code Online (Sandbox Code Playgroud)

Angular 2.0.0-beta.x Plunker示例

另请参阅注入与子组件相同类型的父组件

  • 您可以使用`&lt;template #item let-items&gt; &lt;ng-container * ngFor =“项的项目&gt; &lt;template [ngTemplateOutlet] =” item“ [ngTemplateOutletContext =” {$ implicit:items?.children}“&gt; &lt; / ng-container&gt; &lt;/ template&gt;``&lt;ng-container * ngFor =“让项目项&gt; &lt;template [ngTemplateOutlet] =” item“ [ngTemplateOutletContext =” {$ implicit:items?.children}“&gt; &lt;/ ng-container&gt;。不要指望此代码能正常工作,我只是试图在没有提供完整工作示例的情况下将其理解(抱歉,没有时间) (2认同)
  • 谢谢你会探索这个:)并告诉你.为什么我要求单一范围是因为我正在创建一个具有不可预测的子节点程度的上下文菜单.在单击任何子节点时,我需要最终在包含上下文菜单的Component中捕获该事件.现在,如果我有递归组件树,因为我们没有广角在角度2冒泡将事件发送到单个节点的树的父节点将是一个痛苦. (2认同)
  • @jackOf所有我都有同样的问题,我还需要"保留范围"并找到这个[使用ng-template with ngTemplateOutlet的替代解决方案](https://gist.github.com/arniebradfo/5cf89c362cc216df6fc1d9ca4d536b72).我还在经历它,但看起来很有希望. (2认同)
  • Plunker 需要进行此更改才能工作:/sf/answers/4514658081/ (2认同)

Ped*_*ani 10

usingng-template是解决递归 DOM 问题的最佳解决方案。

@Component({
  selector: 'tree-node',
   template: `
     <ng-container *ngTemplateOutlet="tree;context:{node:node}">
     </ng-container>

     <ng-template #tree let-node="node">
       <div>{{node.name}}</div>
       <ul *ngIf="node.children && node.children.length > 0">
         <ng-container *ngFor="let child of node.children">
           <li>
             <ng-container *ngTemplateOutlet="tree;context:{node:child}">
             </ng-container>
           </li>
         </ng-container>
       </ul>
     </ng-template>
   `
})
export class TreeNode {
    @Input() node;
}
Run Code Online (Sandbox Code Playgroud)

无需将组件添加到directives: []@Component().

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <tree-node [node]="node"></tree-node>
    </div>
  `
})
export class App {

  node = {
    name: 'root', children: [
      { name: 'a', children: [] },
      {
        name: 'b', children: [
          { name: 'b-1', children: [] },
          {
            name: 'b-2', children: [
              { name: 'b-2-1', children: [] },
              { name: 'b-2-2', children: [] },
              { name: 'b-2-3', children: [] }
            ]
          }
        ]
      },
      {
        name: 'c', children: [
          { name: 'c-1', children: [] },
          { name: 'c-2', children: [] }
        ]
      },
    ]
  };

}
Run Code Online (Sandbox Code Playgroud)

输出:

    • 一种
      • b-1
      • b-2
        • b-2-1
        • b-2-2
        • b-2-3
    • C
      • c-1
      • c-2

HTML:

<tree-node>
    <div>root</div>
    <ul>
        <li>
            <div>a</div>
        </li>
        <li>
            <div>b</div>
            <ul>
                <li>
                    <div>b-1</div>
                </li>
                <li>
                    <div>b-2</div>
                    <ul>
                        <li>
                            <div>b-2-1</div>
                        </li>
                        <li>
                            <div>b-2-2</div>
                        </li>
                        <li>
                            <div>b-2-3</div>
                        </li>
                    </ul>
                </li>
            </ul>
        </li>
        <li>
            <div>c</div>
            <ul>
                <li>
                    <div>c-1</div>
                </li>
                <li>
                    <div>c-2</div>
                </li>
            </ul>
        </li>
    </ul>
</tree-node>
Run Code Online (Sandbox Code Playgroud)


Sha*_*ews 6

Angular 4递归组件示例:https://plnkr.co/edit/IrW82ye4NKK8cYEPxsFc?p = preview

链接示例的摘录:

//our root app component
import {Component, NgModule, VERSION, Input} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'

@Component({
  selector: 'tree-node',
  template: `
  <div>{{node.name}}</div>
  <ul>
    <li *ngFor="let node of node.children">
      <tree-node  [node]="node"></tree-node>
    </li>
  </ul>
`
})
export class TreeNode {
  @Input() node;
}

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <tree-node [node]="node"></tree-node>
    </div>
  `
})
export class App {
  constructor() {
    this.name = 'Angular2 (Release Candidate!)'
  }

  node = {name: 'root', children: [
    {name: 'a', children: []},
    {name: 'b', children: []},
    {name: 'c', children: [
      {name: 'd', children: []},
      {name: 'e', children: []},
      {name: 'f', children: []},
     ]},
  ]};  
}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App, TreeNode ],
  bootstrap: [ App ]
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)

这个答案是社区维基,因为示例链接是从GünterZöchbauer的答案中复制的.我将代码包含在问题正文中以避免链接腐烂.