如何在angular 4
中创建上下文菜单?不幸的是,html上下文菜单不起作用。
所以我想创建一个组件并在光标坐标处右键单击显示它,但是如何实现呢?
e.g。
<ul>
<li (click)="showContextMenuComponent">example</li>
</ul
答案 0 :(得分:25)
我发现你所有的解决方案都非常复杂且难以定制,因为我刚刚开始,我只想用组件和事件绑定来解决这个问题。 所以我的ContextMenu是一个输入值为x和y的组件,右键单击它的ParentComponent顶部显示:)
所以这是:
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==true">
<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样式等。 希望这可以帮助:)玩得开心!
答案 1 :(得分:6)
您可以尝试使用ngx-contextmenu库。查看演示here
如果您使用角度版本4,请考虑使用ngx-contextmenu@1.3.5
答案 2 :(得分:2)
解决方案:(已通过Angular 9测试):
在HTML中:
<div (click)="itemClicked($event);" (contextmenu)="itemClicked($event);">
Click Me!!!
</div>
在TS中:
itemClicked($event) {
console.log($event);
/* Use the following properties to differentiate between left and right click respectively.
* $event.type will be "click" or "contextmenu"
* $event.which will be "1" or "3"
*/
// To prevent browser's default contextmenu
$event.preventDefault();
$event.stopPropagation();
// To show your modal or popover or any page
this.openQuickDialog($event); // FYI, this line calls my other method to open Popover dialog.
}
Here is a live example使用棱角材质菜单。右键单击某个项目时,它将菜单的位置设置为鼠标位置并打开它。
我发布了这个答案;以防万一可能会帮助像我这样的人。
答案 3 :(得分:0)
答案 4 :(得分:0)
在 User9132 的GREAT解决方案上进一步构建(请参见上文),您可以动态构建上下文菜单。这样,您可以重复使用通用上下文菜单组件。
parent.component.html: 右键单击列表项。最后,允许处理选定的菜单项。
library(ggplot2)
library(shiny)
a <- c(1,2,3,4,5,6)
b <- c(50,100,40,30,20,80)
mydata <- cbind(a,b)
mydata <- as.data.frame(mydata)
ui <- fluidPage (
headerPanel("basic app"),
sidebarPanel(
sliderInput("slider",
label = "Time elapsed",
min = min(mydata$a),
max = max(mydata$a),
value = min(mydata$a), step = 1,
animate =
animationOptions(interval = 200, loop = TRUE))
),
mainPanel(
plotOutput("plot")
)
)
server <- function(input, output) {
output$plot <- renderPlot({
plotdata <- mydata[1:which(input$slider==mydata$a),]
p <- ggplot(plotdata,aes(x = a,y = b))
if(nrow(plotdata)==1) {
p + geom_point()
} else {
p + geom_line()
}
})
}
parent.component.ts: 父级确定菜单项并作用于所选菜单项。我开始在屏幕上放置上下文菜单,以便它不会从屏幕上掉下来。也许这需要改进-不客气。
<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>
contextmenu.component.html: 单击菜单项后,它将传播到父级以处理选择。
@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.ts:
<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>