【问题标题】:How to create a tree like structure with different views in angular如何创建具有不同角度视图的树状结构
【发布时间】:2021-06-20 15:26:39
【问题描述】:

我正在尝试使用递归 html 创建树视图。如果树的所有节点看起来都相似,那么一切正常,但在我的情况下,父母和孩子看起来不同,但孩子和孙子看起来一样。因此,我在父组件中嵌套了一个子组件,为了生成大子组件,我只需递归调用相同的子组件,如下所示:

parent.component.html

<div *ngFor="let div of divsArray; index as mainIdx" class="main-container" #mainDiv>
  <button (click)="addChild(mainIdx)"><i class="fa fa-plus"></i></button>
  <button (click)="addSibling(mainIdx)"><i class="fa fa-plus"></i></button>
  <button (click)="removeSibling(mainIdx)"><i class="fa fa-minus"></i></button>
  <app-child  *ngFor="let child of div.childArray" [childData]="child"></app- 
  child>
 </div>

parent.component.ts

    divsArray: any[]=[{'childArray':[]}];

    addSibling(){
    this.divsArray.push({'childArray':[]});
    }

    ngAfterViewInit(){
    }

   removeSibling(divIndex: number){
    this.divsArray.splice(divIndex,1);
   }

   addChild(pIndex: number){
     this.divsArray[pIndex].childArray.push({'grandChild':[]});
   }

child.component.html

    <div class="child-container">
    <button (click)="addChild()"><i class="fa fa-plus"></i></button>
    <button (click)="removeChild()"><i class="fa fa-minus"></i></button>
    <app-child *ngFor="let child of childData.grandChild;"></app-child>
    </div>

child.component.ts

   @Input() childData: any;

   addChild(){
    this.childData.grandChild.push({'greatGrandChild':[]})
  }

我在这里面临的问题是,当我尝试为孙子添加一个子时,我收到一条错误消息,提示“无法读取未定义的属性孙子”。当我第三次单击 addChild 按钮时会发生这种情况(即为孙子添加一个孩子)。这个“孙子”是 childData 对象中的一个数组,我作为输入属性从父级传递。有人可以帮我解决这个问题,或者建议一些方法来实现具有不同视图的父节点和子节点的树状结构。谢谢!

【问题讨论】:

  • 嗨,你能创建一个堆栈闪电战并发布问题吗?
  • 您得到 TypeError 的原因是 1)您没有在 child.component.html 中将 childData 传递给 app-child 和 2)您可能错误地访问了模型中的属性。我强烈建议您正确指定输入的类型(以及与此相关的所有其他属性),以便在构建时捕获此类错误。
  • @SachithRukshan 在这里完成 angular-szempj.stackblitz.io, stackblitz.com/edit/…
  • 您的 childData 似乎未定义,请检查您传递给子组件的数据
  • @DanMacák 非常感谢,这正是我所需要的。

标签: javascript html angular


【解决方案1】:

child.component.html

  <app-child *ngFor="let child of childData.grandChild;" [childData]="child"></app-child>

需要设置childData输入

child.component.ts

  addChild() {
    this.childData.grandChild.push({ grandChild: [] });
  }

使用“greatGrandChild”、“greatGreatGrandChild”访问 childData 的子项是额外的工作,因为您还必须在访问它之前弄清楚正确的字段是什么,并且 get 创建下一个字段名称并将第一个字母大写等。

编辑:如果您想在单击“-”时删除当前节点及其子节点

child.component.html

  <app-child *ngFor="let child of childData.grandChild;" [childData]="child" (remove)="removeChildren()"></app-child>

child.component.ts

  @Output() remove = new EventEmitter<string>();
  addChild() {
    this.childData.grandChild.push({ grandChild: [] });
  }

  removeMe() {
    this.remove.emit(null);
  }

  removeChildren() {
    this.childData.grandChild = [];
  }

【讨论】:

  • 我这样做了,效果很好,但现在的问题是如何删除这些。我需要删除我单击删除按钮的孩子及其孩子。
  • 我已经使用输出更新了我的答案以包含它。 check this angular doc for more on outputs
  • 嘿!这适用于所有孙节点,但不适用于第一个子节点
  • 我已经为您提供了如何在子节点上实现这一目标的代码。这是使用事件发射器和输出的相同解决方案,所以我会让你弄清楚实现。
猜你喜欢
  • 1970-01-01
  • 2019-08-18
  • 2015-01-27
  • 2017-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多