Как контекстное меню с угловым 4
Как создать контекстное меню в angular 4
? К сожалению, контекстное меню html не работает.
Поэтому я хочу создать компонент и отобразить его правой кнопкой мыши по координатам курсора, но как это реализовать?
например
<ul>
<li (click)="showContextMenuComponent">example</li>
</ul
Ответы
Ответ 1
Я нашел все ваши решения довольно сложными и сложными для настройки, и, поскольку я только начал, я хотел решить эту проблему только с помощью компонентов и привязки к событиям.
Таким образом, My ContextMenu - это компонент с входными значениями x и y, который отображается правой кнопкой мыши в верхней части его ParentComponent :)
Пример Stackblitz
Итак, вот оно:
Parent.component.ts
export class parentComponent {
contextmenu = false;
contextmenuX = 0;
contextmenuY = 0;
//activates the menu with the coordinates
onrightClick(event){
this.contextmenuX=event.clientX
this.contextmenuY=event.clientY
this.contextmenu=true;
}
//disables the menu
disableContextMenu(){
this.contextmenu= false;
}
parent.component.html
<!-- your whole html is wrapped in a div so anywhere you click you disable contextmenu,
also the div is responsible for suppressing the default browser contextmenu -->
<div (click)="disableContextMenu()" oncontextmenu="return false;">
<!-- this is the usage -->
<ul>
<li (contextmenu)="onrightClick($event)">right click me!</li>
</ul>
<!--you have to write this only once in your component-->
<div *ngIf="contextmenu">
<app-contextmenu [x]="contextmenuX" [y]="contextmenuY"></app-contextmenu>
</div>
</div>
Это само контекстное меню:
contextmenu.component.ts
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-contextmenu',
})
export class ContextmenuComponent{
constructor() { }
@Input() x=0;
@Input() y=0;
}
contextmenu.component.html
<div class="contextmenu" [ngStyle]="{'left.px': x, 'top.px': y}">
this is your contextmenu content
</div>
contextmenu.component.css
.contextmenu{
position: absolute;
}
Теперь вы можете применять свои собственные анимации, CSS-стили и т.д. как обычно с компонентом.
Надеюсь, что это может помочь :) веселиться!
Ответ 2
Вы можете попробовать библиотеку ngx-contextmenu. Проверьте демо здесь
Если у вас угловая версия 4, подумайте об использовании [email protected]
Ответ 3
Вы можете попробовать официальные компоненты углового материала на странице https://material.angular.io/components/menu/overview.
Ответ 4
Лучшее решение - через пузырь событий в прослушивании меню
{
triggeredByMenu = true
// logic
}
в прослушивателе документов
{
if (!triggeredByMenu || Menu.show) Menu.close()
// logic
}
Ответ 5
Я создал настраиваемое контекстное меню с компонентом, любой из которых может взять идею из него, может создавать свои собственные.
здесь ссылка
https://github.com/ieammac/angular-4-custom-context-menu
Ответ 6
Основываясь далее на БОЛЬШОМ решении User9132 (см. выше), вы можете динамически создавать контекстное меню. Таким образом, вы можете повторно использовать компонент общего контекстного меню.
parent.component.html:
Щелкните правой кнопкой мыши элемент списка. Наконец, разрешено обрабатывать выбранный пункт меню.
<div class="row mt-3 ml-1">
<div class="col-11 col-sm-11 col-md-10" (click)="disableContextMenu()" oncontextmenu="return false;">
<div class="geocache-list-height">
<table id="geocaches-list" class="table">
<tbody>
<tr *ngFor="let geocache of mygeocaches" class="d-flex">
...
<td class="col-1" (contextmenu)="onrightClick($event, geocache)"><i class="icon-ellipsis-vert"></i></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<!--you have to write this only once in your component-->
<div *ngIf="contextmenu==true">
<app-contextmenu [x]="contextmenuX" [y]="contextmenuY" [menuitems]="showMenuOptions()" (menuItemSelected)="handleMenuSelection($event)"></app-contextmenu>
</div>
parent.component.ts:
Родитель определяет пункты меню и воздействует на выбранный пункт меню. Я начал размещать контекстное меню на экране, чтобы оно не падало с экрана. Может быть, это нуждается в улучшении - пожалуйста.
@Component({
selector: 'app-geocache-list',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
errorMessage = '';
contextmenu = false;
contextmenuX = 0;
contextmenuY = 0;
contextMenuForGeocache: MyGeocache;
innerWidth: any;
innerHeight: any;
constructor(...) { }
ngOnInit() {
// for determining where the put the context menu -- on the screen ;-)
this.innerWidth = window.innerWidth;
this.innerHeight = window.innerHeight;
...
}
}
showMenuOptions() {
return 'Delete;Navigate;Edit;';
}
onrightClick(event, geocache: MyGeocache ) {
this.contextmenuX = event.clientX - 100;
this.contextmenuY = event.clientY;
this.contextmenu = true;
const menuHeight = this.showMenuOptions().split(';').length;
const maxY = this.innerHeight - ( menuHeight * 30);
if ( this.contextmenuY > maxY ) {
this.contextmenuY = maxY;
}
}
// disables the menu
disableContextMenu() {
this.contextmenu = false;
}
handleMenuSelection( menuselection: string) {
if ( menuselection === 'Delete') {
...
} else if ( menuselection === 'Navigate') {
...
}
}
}
contextmenu.component.html:
После нажатия на пункт меню он будет передан родительскому элементу для обработки выбора.
<div class="contextmenu" [ngStyle]="{'left.px': x, 'top.px': y}">
<ul class="list-group">
<li class="list-group-item" *ngFor="let menuItem of theMenuItems">
<span (click)="outputSelectedMenuItem( menuItem)">{{ menuItem }}</span>
</li>
</ul>
</div>
contextmenu.component.ts:
@Component({
selector: 'app-contextmenu',
templateUrl: './contextmenu.component.html',
styleUrls: ['./contextmenu.component.css']
})
export class ContextmenuComponent implements OnInit {
constructor() { }
@Input() x = 0;
@Input() y = 0;
@Input() menuitems = '';
theMenuItems = [];
@Output() menuItemSelected = new EventEmitter();
ngOnInit() {
// Build the menu items
this.theMenuItems = this.menuitems.split(';');
}
outputSelectedMenuItem( menuitem: string) {
this.menuItemSelected.emit(menuitem);
}
}