#angular #typescript #ngfor #angular10
#angular #машинописный текст #ngfor #угловой 10
Вопрос:
У меня есть следующий образец набора данных, который поступает с сервера.
[
{
subMenuId: 1,
submenu: 'Users',
menu: 'Administration',
url: '/pms/admin/usrs-dsh',
icon: 'fas fa-cogs',
},
{
subMenuId: 2,
submenu: 'Roles',
menu: 'Administration',
url: '/pms/admin/roles-dsh',
icon: 'fas fa-cogs',
},
{
subMenuId: 3,
submenu: 'Menu Items',
menu: 'Administration',
url: '/pms/admin/menus-dsh',
icon: 'fas fa-cogs',
},
{
subMenuId: 4,
submenu: 'Banks',
menu: 'Administration',
url: '/pms/admin/banks-dsh',
icon: 'fas fa-cogs',
},
{
subMenuId: 5,
submenu: 'Branches',
menu: 'Administration',
url: '/pms/admin/branches-dsh',
icon: 'fas fa-cogs',
},
{
subMenuId: 6,
submenu: 'Dashboard',
menu: 'PD3',
url: '/pms/pd3/dsh',
icon: 'fas fa-cogs',
},
];
И я хочу отобразить эти данные следующим образом. Но в настоящее время при отображении значений основного уровня данных повторяются с каждым значением подуровня.
Ожидаемый результат:
Html-файл:
<tr *ngFor="let m of userPermissions;">
<td>
<label class="ml-3 form-check-label">{{m.menu}}</label>
</td>
<td>
<div>
<input (change)="changeSubMenus($event, m.menu,m.subMenuId)" type="checkbox" class="ml-0 form-check-input">
<label class="ml-3 form-check-label">{{m.submenu}}</label><br>
</div>
</td>
</tr>
TS-файл:
getMenus(){
this.userPermissions = this.adminService.allMenus;
this.userPermissions.forEach((val) =>{
// console.log(val)
// TODO: remove multiple main level values and display sub level values with one main level value
})
}
Есть ли какой-нибудь способ добиться этого? Спасибо
Ответ №1:
Вам необходимо изменить объекты в массиве, чтобы выполнить требуемое требование. Для этого вы можете использовать reduce, как показано ниже.
Вам нужно иметь структуру объекта, подобную приведенной ниже, чтобы упростить задачу
modifiedMenu = [{
menu: < Main Menu 1 > ,
subMenu: [ < submenu item > , < submenu item > , ...]
}, {
menu: < Main Menu 2 > ,
subMenu: [ < submenu item > , < submenu item > , ...]
}, ...]
Итак, исходный
userPermissions = this.menus.reduce((acc, ele) => {
if (acc.length === 0) {
acc.push(this.getModifiedMainMenu(ele));
return acc;
} else {
const existedMenu = acc.find(m => m.menu === ele.menu);
if (existedMenu) {
existedMenu.subMenu.push(this.getSubMenu(ele));
return acc;
} else {
acc.push(this.getModifiedMainMenu(ele));
return acc;
}
}
}, []);
getModifiedMainMenu(obj) {
return {
menu: obj.menu,
subMenu: [this.getSubMenu(obj)]
};
}
getSubMenu(obj) {
return {
menu: obj.menu,
subMenuId: obj.subMenuId,
submenu: obj.submenu,
url: obj.url,
icon: obj.icon
};
}
И в файле шаблона теперь вам нужно 2 ngFor
секунды, чтобы зациклить пункты главного меню и соответствующие пункты подменю, как показано ниже
<tr *ngFor="let m of userPermissions;">
<td>
<label class="ml-3 form-check-label">{{m.menu}}</label>
</td>
<td>
<div *ngFor="let subMenu of m.subMenu">
<input (change)="changeSubMenus($event, subMenu.menu, subMenu.subMenuId)" type="checkbox" class="ml-0 form-check-input">
<label class="ml-3 form-check-label">{{subMenu.submenu}}</label>
</div>
</td>
</tr>