javascript - Dinamik olarak iç içe geçmiş angular material menü
Lütfen bana aşağıdaki problemi nasıl çözebileceğimi söyleyin: Veri modeli nesnesine bağlı olarak farklı iç içe seviyelere sahip dinamik olarak oluşturulmuş bir menü uygulamam gerekiyor. Şu anda, özyinelemeyi kullanarak menüyü bu şekilde oluşturmayı başardık, ancak alt menüye doğrudan [matMenuTriggerFor] özniteliğini atama konusunda bir sorun var. Sorun şu ki, tüm sonraki alt menüler aslında en baştaki menüye referans veriyor, bu yüzden herhangi bir alt menünün üzerine geldiğinizde, orijinal menüye bir "dönüş" oluyor (resimdeki örnek: Öğe içeren menü, örneğin: Device, Extension, Queue, Queue member (alt menü öğeleri ile)). Böylece, birkaç saniyelik bir süre için diğer alt menü çerçevesini görüyorum (resimdeki örnek: alt menü Grouped list), ardından ilk menü aktif oluyor. Elbette, belki de her şeyi doğru yapmamışımdır, bu yüzden buraya yöneliyorum. Lütfen bana yardım edin. Hepinize teşekkür ederim.
imenu-item.ts
export interface IMenuItem {
name: string | string[];
link: string;
subItems: IMenuItem[];
}
dynamic-menu.service.ts
import {Inject, Injectable} from '@angular/core';
import {APP_CONFIG_ROUTES} from '../../../config/routes/app.config.routes';
import {IAppConfigRoutes} from '../../../config/routes/iapp.config.routes';
import {IMenuItem} from './imenu-item';
import {_} from '@biesbjerg/ngx-translate-extract/dist/utils/utils';
@Injectable({
providedIn: 'root'
})
export class DynamicMenuService {
private readonly appConfig: any;
constructor(@Inject(APP_CONFIG_ROUTES) appConfig: IAppConfigRoutes) {
this.appConfig = appConfig;
}
getMenuItems(): IMenuItem[] {
return [
{
name: _('labels.device'),
link: '/' + this.appConfig.routes.device,
subItems: null
},
{
name: _('labels.extension'),
link: '/' + this.appConfig.routes.extension,
subItems: null
},
{
name: _('labels.queue'),
link: '/' + this.appConfig.routes.queue,
subItems: null
},
{
name: _('labels.queueMember'),
link: null,
subItems: [{
name: _('labels.fullList'),
link: '/' + this.appConfig.routes.queueMember.all,
subItems: null
}, {
name: _('labels.groupedList'),
link: '/' + this.appConfig.routes.queueMember.grouped,
subItems: [{
name: 'subName',
link: 'subLink',
subItems: [{
name: 'subSubName1',
link: 'subSubLink1',
subItems: null
}, {
name: 'subSubName2',
link: 'subSubLink2',
subItems: null
}]
}]
}]
}
];
}
}
dynamic-menu.component.ts
import {Component, Input, OnInit} from '@angular/core';
import {IMenuItem} from './imenu-item';
@Component({
selector: 'app-dynamic-menu',
templateUrl: './dynamic-menu.component.html',
styleUrls: ['./dynamic-menu.component.scss']
})
export class DynamicMenuComponent implements OnInit {
dynamicMenuItemsData: IMenuItem[];
constructor(private dynamicMenuService: DynamicMenuService) {
}
ngOnInit() {
this.dynamicMenuItemsData = this.dynamicMenuService.getMenuItems();
}
}
dinamik-menu.bileşen.html
<div>
<ng-container [ngTemplateOutlet]="recursiveListMenuItems"
[ngTemplateOutletContext]="{$implicit: dynamicMenuItemsData}">
</ng-container>
</div>
<ng-template #recursiveListMenuItems let-listMenuItems>
<div *ngFor="let menuItem of listMenuItems">
<ng-container [ngTemplateOutlet]="menuItem.subItems != null ? subMenuItem : simpleMenuItem"
[ngTemplateOutletContext]="{$implicit: menuItem}">
</ng-container>
</div>
</ng-template>
<ng-template #simpleMenuItem let-menuItemArg>
<a class="mat-button"
mat-menu-item
routerLink="{{menuItemArg.link}}">
<span>{{menuItemArg.name | translate}}</span>
</a>
</ng-template>
<ng-template #subMenuItem let-menuItemArg>
<a class="mat-button"
mat-menu-item
routerLink="{{menuItemArg.link}}"
[matMenuTriggerFor]="subItemsMenu">
<span>{{menuItemArg.name | translate}}</span>
<mat-menu #subItemsMenu="matMenu"
[overlapTrigger]="false">
<ng-container [ngTemplateOutlet]="recursiveListMenuItems"
[ngTemplateOutletContext]="{$implicit: menuItemArg.subItems}">
</ng-container>
</mat-menu>
</a>
</ng-template>
Cevap #1
Sonuç olarak, diğerleriyle birkaç benzer probleme dayanarak ortaya çıktı. BURADAN (dinamik iç içe menü örneği) ve BURADAN (mat-menu'nun açıldığında hemen kaybolması problemi) alınan örnekler bunu çözmeye yardımcı oldu (son örnekte sadece zone.js'i npm ile güncellemek yeterliydi)
Cevap #2
Geç cevap verdiğim için özür dilerim, ama belki hala işe yarar bulabilirsiniz.
Bence bunu oldukça düzenli bir şekilde yapan ng-action-outlet adında küçük bir kütüphane yazdım.
Böyle görünüyor:
group: ActionGroup;
constructor(private actionOutlet: ActionOutletFactory) {
this.group = this.actionOutlet.createGroup();
this.group.createButton().setIcon('home').fire$.subscribe(this.callback);
this.group.createButton().setIcon('settings').fire$.subscribe(this.callback);
}
<ng-container *actionOutlet="group"></ng-container>
DEMO: https://stackblitz.com/edit/ng-action-outlet-demo?file=src/app/app.component.ts
