Доступ к модели представления из обратного вызова контекстного меню с помощью aurelia-slickgrid

Я пытаюсь заменить aurelia-table на aurelia-slickgrid в проекте, над которым работаю. У меня есть ряд действий, которые запускаются, когда пользователь щелкает часть таблицы. Я думал, что контекстное меню будет способом воспроизвести это поведение, но кажется, что в обратном вызове для команды меню у вас нет доступа к модели представления. Например, я хотел бы разрешить пользователю изменять статус клиента из сетки, но для этого мне нужно вызвать функцию, которая отправляет обновление на сервер.

Мое решение состояло в том, чтобы добавить ссылку на модель представления в определение элемента команды. Мой вопрос: это правильный способ справиться с этим?

Спасибо, Росс


person Ross    schedule 27.12.2020    source источник


Ответы (1)


Вам, вероятно, следует использовать меню ячеек вместо контекстного меню, они построены с той же структурой (я знаю, так как я создал эти плагины), единственная разница в том, что меню ячеек (также известное как меню действий) может быть 1 (или больше) столбцы в вашей сетке, в то время как контекстное меню доступно только при нажатии правой кнопки мыши из любого места, но вообще не отображается в сетке (короче говоря, если вы хотите показать столбец, используйте меню ячеек, иначе контекстное меню, они служат для разных целей, меню Cel обычно предназначено для действия в текущей строке, а контекстное меню — для всей сетки).

Когда вы говорите, что модель представления недоступна в контекстном меню, это не совсем так, во-первых, я не уверен, что вы имели в виду объект элемента, и если это так, то он доступен во втором аргументе args.dataContext, но если вы действительно имеете в виду класс ViewModel вашей Aurelia ViewModel, просто привяжите его с помощью .bind(this) или используйте его встроенный.

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

  whatever() {}
}

Внешний файл

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

Если мы возьмем, например, Cell Menu (столбец меню действий), мы можем написать его так:

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
      }
    }
  }
};

Если вы хотите изменить значение в сетке из обратного вызова действия меню ячейки, вы можете сделать это через объект SlickGrid DataView, который снова доступен косвенно из args.grid, я имею в виду косвенно, потому что вам нужно получить его из объекта сетки, а затем после что вы можете получить от него объект DataView.

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
}

но на самом деле есть другой и более простой способ изменить свойство элемента dataContext. Меню ячейки (и контекстное меню) имеют то, что называется списком параметров, который был создан для этой цели обновления чего-либо в вашем объекте элемента (контекст данных).

Например, если вы хотите изменить флаг, вы можете сделать это следующим образом.

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 },
      ],
    }
  }
};

который создает следующее меню, параметры всегда находятся в верхней части меню введите здесь описание изображения

Весь код, показанный в этом ответе, взят из этого примера 24, который показывает как меню ячейки, так и контекстное меню и связанные с ними меню ячейки — Wiki и Контекстное меню — Wiki

Наконец, я закончу, сказав, что Aurelia-Slickgrid (а я автор) является оболочкой поверх SlickGrid. Если вы будете искать достаточно, вы обнаружите, что можете сделать почти все, используя поиск по слову SlickGrid, и вы найдете много. Есть несколько способов сделать то, что вы хотите сделать, и во многих ситуациях просто помните, что использование обычного JavaScript также поможет вам (.bind(this) — один из них)

person ghiscoding    schedule 29.12.2020