Как отобразить сложные данные или изменить шаблон для первого и последнего элементов в ngFor?

#angular

#угловатый

Вопрос:

Подобные вопросы уже задавались, но мой немного отличается. Или я просто не нашел подходящего варианта?

Я использую Angular 10, и мне нужно отобразить сложные данные родительского элемента со списком дочерних элементов:

     data = [
      { Name: 'n1', Items: [{ i1: '0000', i2: '000' }] },
      {
        Name: 'n2',
        Items: [
          { i1: '11', i2: '1' },
          { i1: '2', i2: '222222' },
        ],
      },
    ];
 

HTML:

     <table border=1>
      <head>
        <tr>
          <th rowspan="2">Name</th>
          <th colspan="2">Items</th>
        </tr>
        <tr>
          <th>I1</th>
          <th>I2</th>
        </tr>
      </thead>
      <body>
          <tr *ngFor="let d of data">
            <td>{{ d.Name }}</td>
            <td colspan="2">
              <table border=1>
                <tr *ngFor="let item of d.Items">
                  <td>{{ item.i1 }}</td>
                  <td>{{ item.i2 }}</td>
                </tr>
              </table>
            </td>
          </tr>
        </tbody>
    </table>
 

Очевидная проблема заключается в том, что ширина ячеек элементов для разных элементов данных может иметь разную ширину.

Чтобы преодолеть это, я бы хотел избежать создания отдельной таблицы внутри ячейки «элементы», а использовать ячейки «основной» таблицы. Например, что-то вроде этого:

     <tbody>
      <ng-container *ngFor="let d of data">
        <tr>
          <td attr.rowspan="{{ d.Items.length }}">{{ d.Name }}</td>
          <ng-container *ngFor="let item of d.Items">
            <tr>
              <td>{{ item.i1 }}</td>
              <td>{{ item.i2 }}</td>
            </tr>
          </ng-container>          
        </tr>
      </ng-container>
    </tbody>
 

Хотя мне нужно как-то «скрыть» первое «для каждого первого элемента и «для самого последнего».

Когда я написал вопрос и хорошо объяснил его (надеюсь) самому себе, я считаю, что смогу достичь цели, изменив «html» внутри » для 1-й и последней записей, используя эту идею:

     <tbody>
      <ng-container *ngFor="let d of data">
        <tr>
          <td attr.rowspan="{{ d.Items.length }}">{{ d.Name }}</td>
            <ng-container *ngFor="let item of d.Items; let i=index">
              <ng-container *ngIf=" i !== 0 " >
                <tr>
              </ng-container>                
                <td>{{ item.i1 }}</td>
                <td>{{ item.i2 }}</td>
              <ng-container *ngIf=" i !== d.Items.length-1 " >
                </tr>
              </ng-container>                 
            </ng-container>          
        </tr>
      </ng-container>
    </tbody>
 

Но этот код выдает мне ошибку:

Неожиданный закрывающий тег «tr»

Пожалуйста, посоветуйте, как я могу отобразить сложные данные таким образом? Или как правильно скрыть некоторые теги с помощью -в «ng-контейнере»?

Спасибо!

Комментарии:

1. для первого и последнего элемента u может получить значения true false, используя ngFor следующим образом. *ngFor="let d of data; let first = first; let last=last;" . angular предоставляет следующие переменные. index , first , last , even , odd .

Ответ №1:

Я полагаю, что ниже приведено то, чего вы пытаетесь достичь

 <table border=1>
    <thead>
        <tr>
            <th rowspan="2">Name</th>
            <th colspan="2">Items</th>
        </tr>
        <tr>
            <th>I1</th>
            <th>I2</th>
        </tr>
    </thead>
    <tbody>
    <ng-container *ngFor="let d of data">
      <ng-container *ngFor="let item of d.Items; let first=first">
        <tr>
          <td  *ngIf='first' [attr.rowspan]='d.Items.length'>{{ d.Name }}</td>
          <td>{{ item.i1 }}</td>
          <td>{{ item.i2 }}</td>
        </tr>
      </ng-container>
    </ng-container>
    </tbody>
</table>
 

Обратите внимание на строку [attr.rowspan]='d.Items.length' . Это гарантирует правильное выравнивание таблицы

Ниже приведена демонстрационная версия stackblitz

Комментарии:

1. Да, это имеет смысл. Простой и читаемый, как и должно быть. Большое спасибо!