Невозможно выполнить итерацию с помощью ngFor

#javascript #angular #typescript

#javascript #угловой #typescript

Вопрос:

У меня есть компонент, который получает данные из серверной части и группирует их

Вот код

  getRecruitmentAgencyClientPositions(): void {
    this._recruitmentAgencyClientsService.getRecruitmentAgencyClientPositions(this.recruitmentAgencyClientId).subscribe(r => {
        this.groupedArray = _.groupBy(r.items, 'groupIdentifier');
        console.log(this.groupedArray);
    });
}
 

Вот как я получил это так

  {
  "57a5bcdf-fdf0-494a-ba94-8c50ebb716cf": [
    {
      "groupIdentifier": "57a5bcdf-fdf0-494a-ba94-8c50ebb716cf",
      "salary": 100,
      "commission": 5,
      "recruitmentAgencyClientId": 10,
      "isDeleted": false,
      "deleterUserId": null,
      "lastModifierUserId": null,
      "creationTime": "2020-11-27T18:00:48 02:00",
      "creatorUserId": 3,
      "id": 5
    }
  ],
  "00000000-0000-0000-0000-000000000000": [
    {
      "groupIdentifier": "00000000-0000-0000-0000-000000000000",
      "salary": 100,
      "commission": 20,
      "recruitmentAgencyClientId": 10,
      "isDeleted": false,
      "deleterUserId": null,
      "lastModifierUserId": null,
      "creationTime": "2020-11-30T17:23:18 02:00",
      "creatorUserId": 3,
      "id": 7
    },
    {
      "groupIdentifier": "00000000-0000-0000-0000-000000000000",
      "salary": 123,
      "commission": 1,
      "recruitmentAgencyClientId": 10,
      "isDeleted": false,
      "deleterUserId": null,
      "lastModifierUserId": null,
      "creationTime": "2020-11-30T17:23:42 02:00",
      "creatorUserId": 3,
      "id": 8
    },
    {
      "groupIdentifier": "00000000-0000-0000-0000-000000000000",
      "salary": 100,
      "commission": 20,
      "recruitmentAgencyClientId": 10,
      "isDeleted": false,
      "deleterUserId": null,
      "lastModifierUserId": null,
      "creationTime": "2020-11-30T17:30:47 02:00",
      "creatorUserId": 3,
      "id": 9
    },
    {
      "groupIdentifier": "00000000-0000-0000-0000-000000000000",
      "salary": 20,
      "commission": 20,
      "recruitmentAgencyClientId": 10,
      "isDeleted": false,
      "deleterUserId": null,
      "lastModifierUserId": null,
      "creationTime": "2020-11-30T17:31:36 02:00",
      "creatorUserId": 3,
      "id": 10
    },
    {
      "groupIdentifier": "00000000-0000-0000-0000-000000000000",
      "salary": 20,
      "commission": 1,
      "recruitmentAgencyClientId": 10,
      "isDeleted": false,
      "deleterUserId": null,
      "lastModifierUserId": null,
      "creationTime": "2020-11-30T17:35:20 02:00",
      "creatorUserId": 3,
      "id": 11
    },
    {
      "groupIdentifier": "00000000-0000-0000-0000-000000000000",
      "salary": 20,
      "commission": 3,
      "recruitmentAgencyClientId": 10,
      "isDeleted": false,
      "deleterUserId": null,
      "lastModifierUserId": null,
      "creationTime": "2020-11-30T17:35:26 02:00",
      "creatorUserId": 3,
      "id": 12
    },
    {
      "groupIdentifier": "00000000-0000-0000-0000-000000000000",
      "salary": 666,
      "commission": 3,
      "recruitmentAgencyClientId": 10,
      "isDeleted": false,
      "deleterUserId": null,
      "lastModifierUserId": null,
      "creationTime": "2020-11-30T17:42:08 02:00",
      "creatorUserId": 3,
      "id": 13
    },
    {
      "groupIdentifier": "00000000-0000-0000-0000-000000000000",
      "salary": 111,
      "commission": 23,
      "recruitmentAgencyClientId": 10,
      "isDeleted": false,
      "deleterUserId": null,
      "lastModifierUserId": null,
      "creationTime": "2020-11-30T17:42:49 02:00",
      "creatorUserId": 3,
      "id": 14
    },
    {
      "groupIdentifier": "00000000-0000-0000-0000-000000000000",
      "salary": 2,
      "commission": 2,
      "recruitmentAgencyClientId": 10,
      "isDeleted": false,
      "deleterUserId": null,
      "lastModifierUserId": null,
      "creationTime": "2020-11-30T17:42:52 02:00",
      "creatorUserId": 3,
      "id": 15
    }
  ]
}
 

И я пытаюсь генерировать таблицы в соответствии с группировкой следующим образом

     <div *ngFor="let item of groupedArray">
<div class="primeng-datatable-container positions-table" [busyIf]="primengTableHelper.isLoading">
    <p-table
        #dataTablech
        [value]="item"
        rows="{{ primengTableHelper.defaultRecordsCountPerPage }}"
        [paginator]="false"
        dataKey="id"
        ScrollWidth="100%"
    >
        <ng-template pTemplate="header">
            <tr>
                <th>
                    {{ 'Id' | localize }}
                </th>
                <th>
                    {{ 'Salary' | localize }}
                </th>
                <th>
                    {{ 'Commission' | localize }}
                </th>              
            </tr>
        </ng-template>

        <ng-template pTemplate="body" let-record="$implicit">
            <tr>
                <td>{{ item.id }}</td>
                <td>{{ item.salary }} £</td>
                <td>{{ item.commission }} %</td>
            </tr>
        </ng-template>
    </p-table>
    <div class="primeng-no-data" *ngIf="!primengTableHelper.records">
        {{ 'NoData' | localize }}
    </div>
</div>
</div>
 

Но я получаю ошибку, подобную этой

Ошибка: не удается найти другой поддерживающий объект ‘[object Object]’ типа ‘object’. ngFor поддерживает привязку только к итерациям, таким как массивы

Как я могу это исправить?

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

1. Как показывает ваш журнал, groupedArray это объект, а не список, отображаемый {} списками, которые вы хотите выполнить, похоже, находятся внутри свойств объекта, т.е.: 57a5bcdf-fdf0-494a-ba94-8c50ebb716cf

2. groupedArray не является массивом. Это объект, свойствами которого являются массивы.

3. Как я могу выполнить итерацию через массивы из объектов? @Fussel

4. Как я могу выполнить итерацию через массивы из объектов? @jarmod

5. Вероятно, у вас уже был array ( r.items ) до того, как вы использовали Lodash для его группировки.

Ответ №1:

Как следует из ошибки, ngFor используется только для итерации по массивам, а не объектам. Чтобы превратить объект в массив, вы можете использовать, например Object.values() , или Object.keys() . В вашем случае ключи совпадают с property groupIdentifier , поэтому я предлагаю вам использовать Object.values() .

Самый простой пример — добавить Object.values в ngFor :

 *ngFor="let item of Object.values(groupedArray)"
 

Пожалуйста, обратите внимание, что результатом будет взаимодействие по:

 [
  [
    {
      "groupIdentifier": "57a5bcdf-fdf0-494a-ba94-8c50ebb716cf",
      "salary": 100,
      "commission": 5,
      "recruitmentAgencyClientId": 10,
      "isDeleted": false,
      "deleterUserId": null,
      "lastModifierUserId": null,
      "creationTime": "2020-11-27T18:00:48 02:00",
      "creatorUserId": 3,
      "id": 5
    }
  ],
  [
    {
      "groupIdentifier": "00000000-0000-0000-0000-000000000000",
      "salary": 100,
      "commission": 20,
      "recruitmentAgencyClientId": 10,
      "isDeleted": false,
      "deleterUserId": null,
      "lastModifierUserId": null,
      "creationTime": "2020-11-30T17:23:18 02:00",
      "creatorUserId": 3,
      "id": 7
    },
    ...
  ]

]

 

Это означает, что вам действительно понадобится second ngFor .

Лучшим решением этой проблемы было бы правильное отображение значений при получении их из серверной части. Например:

 getRecruitmentAgencyClientPositions(): void { 
    this._recruitmentAgencyClientsService.getRecruitmentAgencyClientPositions(this.recruitmentAgencyClientId).subscribe(r => {
        const groupedObject = _.groupBy(r.items, 'groupIdentifier'); // object of arrays
        const groupedArrays = Object.values(groupedObject); // array of arrays
        this.groupedArray = groupedArrays.reduce((flatArray, current) => flatArray.concat(current), []); //flatting arrays, final result
        console.log(this.groupedArray);
    });
}
 

Этот способ *ngFor="let item of groupedArray" должен работать как шарм.

ОБНОВЛЕНИЕ Для итерации по группе вы можете просто не сглаживать массивы.

 getRecruitmentAgencyClientPositions(): void { 
    this._recruitmentAgencyClientsService.getRecruitmentAgencyClientPositions(this.recruitmentAgencyClientId).subscribe(r => {
        const groupedObject = _.groupBy(r.items, 'groupIdentifier'); // object of arrays
        this.groupedArray = Object.values(groupedObject); // array of arrays
        console.log(this.groupedArray);
    });
}
 

Таким образом, groupedArray это массив, и каждый элемент в этом массиве представляет собой одну группу.

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

1. Но мне нужны сгруппированные данные, потому что мне нужно сгенерировать таблицу для каждой группы. Так что это решение мне не подходит: (

2. Я обновил сообщение. Пожалуйста, проверьте, является ли обновленный ответ решением вашей проблемы 🙂

Ответ №2:

Данные, которые вы получаете в groupedArray, не являются массивом. это объект с 2 массивами внутри него.

Если я не ошибаюсь, первый массив: «00000000-0000-0000-0000-000000000000», второй массив: «57a5bcdf-fdf0-494a-ba94-8c50ebb716cf».

если вы хотите преобразовать это в массив, переместите содержимое обоих массивов в один массив, после чего вы сможете выполнить итерацию.

Вот так :

 function convertToArray(array){
    let gArray=[];
    array["00000000-0000-0000-0000-000000000000"].forEach(data=>{
        gArray.push(data);
      });

    array["57a5bcdf-fdf0-494a-ba94-8c50ebb716cf"].forEach(data=>{
         gArray.push(data)
      });
   return gArray;
}
 

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

1. Но мне не нужно объединять их в один массив, все указывает на то, что мне нужно его сгруппировать