简体   繁体   English

使用 aurelia-slickgrid 从上下文菜单回调访问视图 model

[英]Accessing view model from context menu callback with aurelia-slickgrid

I'm trying to replace aurelia-table with aurelia-slickgrid in a project I'm working on.我正在尝试在我正在进行的项目中用 aurelia-slickgrid 替换 aurelia-table。 I have a number of actions that are triggered when the user clicks an part of a table.当用户单击表格的一部分时,我会触发许多操作。 I was thinking the context menu would be a way to replicate that behavior, but it seems in the callback for a menu command you don't have access to the view model.我认为上下文菜单将是复制该行为的一种方式,但似乎在菜单命令的回调中您无权访问视图 model。 For example, I would like to be able to allow the user to change the status of a customer from the grid, but do that, I have to call the function that sends the update to the server.例如,我希望能够允许用户从网格中更改客户的状态,但是这样做,我必须调用将更新发送到服务器的 function。

My solution was to add a reference to the view model in the command item definition.我的解决方案是在命令项定义中添加对视图 model 的引用。 My question is, is this the right way to handle this?我的问题是,这是处理这个问题的正确方法吗?

Thanks, Ross谢谢,罗斯

You should probably use the Cell Menu instead of a Context Menu, they are built with the same structure (I know since I created those plugins), the only difference is that the Cell Menu (aka Action Menu) can be 1 (or more) column(s) in your grid while the Context Menu is only available via right+click from anywhere but is not visible at all in the grid (in short, if you want to show a column then use Cell Menu else Context Menu, they serve different purpose, a Cel Menu is typically for current row action while a Context Menu is for the entire grid).您可能应该使用单元格菜单而不是上下文菜单,它们使用相同的结构构建(我知道,因为我创建了这些插件),唯一的区别是单元格菜单(又名操作菜单)可以是 1(或更多)网格中的列,而上下文菜单只能通过右键单击从任何位置获得,但在网格中根本不可见(简而言之,如果您想显示列,则使用单元格菜单,否则使用上下文菜单,它们提供不同的目的,Cel 菜单通常用于当前行操作,而上下文菜单用于整个网格)。

When you say that the view model is not accessible in the Context Menu well that is not totally true, first off I'm not sure if you meant the item object and if that is the case then it is available in the 2nd argument args.dataContext but if you really mean the ViewModel Class of your Aurelia ViewModel, then just bind to it with .bind(this) or use it inline.当您说在上下文菜单中无法访问视图 model 时,这并不完全正确,首先我不确定您是否指的是 object 项目,如果是这种情况,那么它在第二个参数args.dataContext但如果你真的是指 Aurelia ViewModel 的 ViewModel Class,那么只需使用.bind(this)绑定到它或内联使用它。

export class MyDemo {
  initializeGrid() {
    this.gridOptions = { 
      contextMenu: {
        command: myExternalContextMenu.bind(this), // bind this to external function
      }
    };
  }

  whatever() {}
}

External File外部文件

export function myContextMenu(e, args) {
  const item = args.dataContext;
  this.whatever(); // MyDemo class is available because of its bounded context
}

If we take for example the Cell Menu (Action Menu Column), we can write it this way如果我们以单元格菜单(Action Menu Column)为例,我们可以这样写

this.columnDefinitions = [
  { id: 'firstName', field: 'firstName', name: 'First Name' },
  { id: 'lastName', field: 'lastName', name: 'Last Name' },
  // ... more column defs
  {
    id: 'action', name: 'Action', field: 'action', width: 110, maxWidth: 200,
    excludeFromExport: true,    // you typically don't want this column exported
    formatter: actionFormatter, // your Custom Formatter
    cellMenu: {
      action: (e, args) => {
        console.log(args.dataContext, args.column); // action callback.. do something
      }
    }
  }
};

If you want to change a value in the grid from the Cell Menu action callback, you can do that via the SlickGrid DataView object which is available again indirectly from the args.grid , I mean indirectly because you need to get it from the Grid Object then after that you can get the DataView object from it.如果您想从单元格菜单操作回调中更改网格中的值,您可以通过 SlickGrid DataView object 来执行此操作,这又可以从args.grid间接获得,我的意思是间接因为您需要从 Grid Object 获取它然后,您可以从中获取 DataView object。

action: (_event, args) => {
  const dataContext = args.dataContext;
  const grid = args.grid;
  const dataView = args.grid.getData(); // since we use DataView, getData() will return the DataView
  dataView.updateItem({ ...dataContext, status: true }); // update a status flag
  grid.invalidateRow(args.row); // invalidate that row will re-render that specific row
}

but there's actually another, and easier, way of changing a property of the item dataContext.但实际上还有另一种更简单的方法来更改项 dataContext 的属性。 The Cell Menu (and Context Menu) both have what is called an Option List which was created for that purpose of updating something in your item object (data context).单元格菜单(和上下文菜单)都有所谓的选项列表,该列表是为了更新项目 object(数据上下文)中的某些内容而创建的。

For example, if you want to change a flag you can do it this way例如,如果你想改变一个标志,你可以这样做

this.columnDefinitions = [
  { id: 'firstName', field: 'firstName', name: 'First Name' },
  { id: 'lastName', field: 'lastName', name: 'Last Name' },
  // ... more column defs
  {
    id: 'action', name: 'Action', field: 'action', width: 110, maxWidth: 200,
    excludeFromExport: true,    // you typically don't want this column exported
    formatter: actionFormatter, // your Custom Formatter
    cellMenu: {
      optionTitle: 'Change Effort Driven Flag', // optional, add title
      optionItems: [       
        { option: true, title: 'True', iconCssClass: 'fa fa-check-square-o' },
        { option: false, title: 'False', iconCssClass: 'fa fa-square-o' },
        { divider: true, command: '', positionOrder: 60 },
      ],
    }
  }
};

which produces the following menu, the Options are always on the top portion of the menu生成以下菜单,选项始终位于菜单的顶部在此处输入图像描述

All of code shown in this answer comes from this Example 24 that shows both Cell Menu and Context Menus and their associated Cell Menu - Wiki and Context Menu - Wiki此答案中显示的所有代码均来自此示例 24 ,该示例显示了单元格菜单和上下文菜单及其关联的 单元格菜单 - Wiki上下文菜单 - Wiki

Lastly, I'll finish by saying that Aurelia-Slickgrid (which I'm the author of) is a wrapper on top of SlickGrid.最后,我将说 Aurelia-Slickgrid(我是它的作者)是 SlickGrid 之上的一个包装器。 If you search enough, you will find that you can do most probably everything by searching with SlickGrid word and you'll find plenty.如果您搜索得足够多,您会发现您几乎可以通过使用 SlickGrid 单词搜索来完成所有操作,并且您会发现很多。 There's multiple ways to do what you want to do and in many situations just remember that the use of regular JavaScript will also help you ( .bind(this) is one of those)有多种方法可以做您想做的事情,在许多情况下,请记住使用常规 JavaScript 也会对您有所帮助( .bind(this)就是其中之一)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM