Как перебрать массив, который содержит массив того же вида в angular - PullRequest
0 голосов
/ 18 марта 2020

У меня есть angular приложение, которое содержит класс модели Employ следующим образом:

export interface Employee {
name: string;
type: string;
subordinates: Employee[];
}
export declare class EmployeeEntity implements Employee {
name: string;
type: string;
subordinates: EmployeeEntity[];
supervisor?: EmployeeEntity;
constructor(orgStructure: string[], supervisor?: EmployeeEntity);
}

Сотрудник может содержать свойство "подчиненные" в виде массива с тем же типом данных

In В файле member.component.ts указаны значения:

export class ParticipantComponent implements OnInit {

  constructor() { }


  empData: Employee= {
name: "Iron Man",
type: 'CEO',
subordinates: [
    {
        name: "Captain America",
        type: 'VP',
        subordinates: [
            {
                name: "Hawkeye",
                type: 'manager',
                subordinates: []
            },
            {
                name: "Antman",
                type: 'Manager',
                subordinates: []
            }
        ]
    },
    {
        name: "Black Widow",
        type: 'VP',
        subordinates: [
            {
                name: "Hulk",
                type: 'manager',
                subordinates: [
                    {
                        name: "Spiderman",
                        type: 'Intern',
                        subordinates: []
                    }
                ]
            },
            {
                name: "Thor",
                type: 'Manager',
                subordinates: [
                    {
                        name: "Loki",
                        type: 'Team Lead',
                        subordinates: []
                    }
                ]
            }
        ]
    }
]


 };

  ngOnInit(): void {
  }

}

в файле member.component. html, я намерен напечатать значения из класса модели в организационную диаграмму.

<div class = "container">
            <div class="tree"  *ngIf="empData"> 
                    <ul>
                        <li>
                            <a href="#"> {{empData.name}}   <br/>
                                {{empData.type}}
                            </a>

                            <ul>
                                <li *ngFor="let item of empData.subordinates">
                                    <a href="#"> {{item.name}}   <br/>
                                        {{item.type}}
                                    </a>
                                    <ul>
                                        <li *ngFor="let subitem of item.subordinates">
                                                <a href="#"> {{subitem.name}}   <br/>
                                                    {{subitem.type}}
                                                </a>
                                        </li>
                                    </ul>
                                </li>

                            </ul> 
                        </li>
                    </ul>
            </div>
    </div>

Теперь проблема в том, как долго мне нужно продолжать * ngFor, чтобы искать значения . Есть ли в любом случае, который ищет длину массива или некоторые другие логики c, поскольку может быть неограниченное количество значений? Пожалуйста, помогите мне

Вот файл стиля incase.

 * {margin: 0; padding: 0;}

    .tree ul {
        padding-top: 20px; position: relative;

        transition: all 0.5s;
        -webkit-transition: all 0.5s;
        -moz-transition: all 0.5s;
    }

    .tree li {
        float: left; text-align: center;
        list-style-type: none;
        position: relative;
        padding: 20px 5px 0 5px;

        transition: all 0.5s;
        -webkit-transition: all 0.5s;
        -moz-transition: all 0.5s;
    }

    /*We will use ::before and ::after to draw the connectors*/

    .tree li::before, .tree li::after{
        content: '';
        position: absolute; top: 0; right: 50%;
        border-top: 1px solid #ccc;
        width: 50%; height: 20px;
    }
    .tree li::after{
        right: auto; left: 50%;
        border-left: 1px solid #ccc;
    }

    /*We need to remove left-right connectors from elements without 
    any siblings*/
    .tree li:only-child::after, .tree li:only-child::before {
        display: none;
    }

    /*Remove space from the top of single children*/
    .tree li:only-child{ padding-top: 0;}

    /*Remove left connector from first child and 
    right connector from last child*/
    .tree li:first-child::before, .tree li:last-child::after{
        border: 0 none;
    }
    /*Adding back the vertical connector to the last nodes*/
    .tree li:last-child::before{
        border-right: 1px solid #ccc;
        border-radius: 0 5px 0 0;
        -webkit-border-radius: 0 5px 0 0;
        -moz-border-radius: 0 5px 0 0;
    }
    .tree li:first-child::after{
        border-radius: 5px 0 0 0;
        -webkit-border-radius: 5px 0 0 0;
        -moz-border-radius: 5px 0 0 0;
    }

    /*Time to add downward connectors from parents*/
    .tree ul ul::before{
        content: '';
        position: absolute; top: 0; left: 50%;
        border-left: 1px solid #ccc;
        width: 0; height: 20px;
    }

    .tree li a{
        border: 1px solid #ccc;
        padding: 5px 10px;
        text-decoration: none;
        color: #666;
        font-family: arial, verdana, tahoma;
        font-size: 11px;
        display: inline-block;

        border-radius: 5px;
        -webkit-border-radius: 5px;
        -moz-border-radius: 5px;

        transition: all 0.5s;
        -webkit-transition: all 0.5s;
        -moz-transition: all 0.5s;
    }

    /*Time for some hover effects*/
    /*We will apply the hover effect the the lineage of the element also*/
    .tree li a:hover, .tree li a:hover+ul li a {
        background: #c8e4f8; color: #000; border: 1px solid #94a0b4;
    }
    /*Connector styles on hover*/
    .tree li a:hover+ul li::after, 
    .tree li a:hover+ul li::before, 
    .tree li a:hover+ul::before, 
    .tree li a:hover+ul ul::before{
        border-color:  #94a0b4;
    }

1 Ответ

1 голос
/ 18 марта 2020

То, что вы хотите достичь, это рекурсия. У вас есть древовидная структура данных, которую вы хотите просмотреть при рендеринге.

Я бы порекомендовал создать компонент, который может рекурсивно вызывать себя для рендеринга любых дочерних элементов (subordinates).

employee.component.ts

@Component({
  selector: 'employees',
  templateUrl: './employees.component.html'
})
export class EmployeesComponent  {
  @Input() employees: Employee[];
}
<ul *ngIf="employees">
  <li *ngFor="let employee of employees">
    <div>{{employee.name}}</div>
    <div>{{employee.type}}</div>
    <div *ngIf="employee.subordinates?.length > 0">
      <employees [employees]="employee.subordinates"></employees>
    </div>
  </li>
</ul>

Сотрудники отобразят массив Employee, указанный в свойстве @Input(). Если у любого Employee есть подчиненные, компонент будет вызывать себя с этими подчиненными как свойство @Input(). И так далее ...

Это нужно будет удалить из исходных данных, которые также должны быть массивом.

app.component.ts

employees: Employee[] = [{
  name: "Iron Man",
  //... etc
}];
<employees [employees]="employees"></employees>

DEMO: https://stackblitz.com/edit/angular-nfphsl

...