Событие выбора флажков ag-grid слишком медленное, чтобы angular обнаружил изменения - PullRequest
0 голосов
/ 16 июня 2020

Я использую ag-grid с Angular 8. Поскольку я использую его много раз в разных представлениях, я инкапсулировал компонент ag-grid в свою собственную реализацию компонента angular.
Теперь он предварительно настроен, и мне нужно передать только массив для данных таблицы и массив для выбора.

пример:

<myGrid 
    [rowData]="myTableData"
    [(selection)]="mySelection"
    (selectionChange)="onSelectionChange($event)"
>
</myGrid>

На основе выбранных строк на мой взгляд, кнопки включены или отключены. И это очень хорошо работает, когда я нажимаю прямо на строки в ag-сетке.

MyProblem

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

Все остальное в порядке. Выбор производится в таблице, я даже могу записать выбранные строки, срабатывает событие onSelectionChange .. Просто кнопки не получают уведомления.

Мое объяснение

Вид не обновляется после того, как был сделан выбор. Либо событие, обновляющее представление, уже завершено до того, как сделан выбор, либо установка флажков не вызывает обнаружения изменений.

Мое решение

Использование ChangeDetectorRef#detectChanges().

-> Я устанавливаю флажок в своей сетке
-> (в MyGrid компоненте) ag-grid запускает onSelectionChanged функцию
-> событие для @Output испускается вызовом this.selectionChange.emit(this.selection);
-> родительские компоненты реализуют функцию selectionChange($event) и запускают this.changeDetectorRef.detectChanges()

Мой вопрос

ПОЧЕМУ? . Почему angular не обнаруживает изменения, когда я нажимаю на флажки, а только когда я нажимаю где-нибудь еще?

Дополнительные настройки более подробно:

В компоненте MyGrid

@Input('rowData') public rowData: any[] = [];         // the array with the data for my table
@Input('selection') public selection: any[] = [];     // the array that holds my selected rows
@Output() private selectionChange = new EventEmitter<any[]>();  // bi-directional so I can get and set the selection from within my parent component

EDIT
Я добавил сюда полные параметры. Как видите, они довольно просты, поэтому родительский компонент может инициализировать их по мере необходимости.
/ EDIT

 this.agGridOptions = {
  context: {thisComponent: this},
  pagination: true,
  paginationAutoPageSize: true,
  rowDeselection: false,
  rowSelection: this.rowSelectionMode,        // parameterizable
  suppressDragLeaveHidesColumns: true,
  suppressMakeColumnVisibleAfterUnGroup: true,
  groupUseEntireRow: true,
  rowGroupPanelShow: 'always',
  animateRows: true,
  sideBar: this.sideBar,                      // parameterizable
  defaultColDef: this.defaultColDef,          // parameterizable
  columnDefs: this.columnDefs,                // parameterizable
  getRowHeight: this.rowHeight,               // parameterizable
  onModelUpdated: () => this.sizeColumns(),
  onSelectionChanged: () => this. onSelected(),
  onGridReady: ($event) => this.onGridReady($event),
  getContextMenuItems: ($event) => this.getContextMenuItems($event)
};

// and once the onSelectionChanged is triggered this function is called:

onSelected() {
  this.selection = this.agGridApi.getSelectedRows();  // I update my bi-directional array for the selected rows
  this.selectionChange.emit(this.selection);          // and trigger the selectionChange event so the parent component knows that something happened
}

Теперь в моем родительском компоненте я должен реализовать это:

onSelectionChange($event: any[]) {
   this.changeDetectorRef.detectChanges();            // otherwise angular won't update my buttons
}

EDIT
А вот как инициализируется массив с columnDefs:

this.columnDefs.push(
     // some factory function that creates something like this:
     {
        headerName : 'Some Column',     // ex: "Employee"
        field : 'fieldOfTheModelClass', // ex: employee.name
        filter : 'agTextColumnFilter',  // (for example)
        checkboxSelection : true,       // the checkbox causes the problem
        valueGetter :  null,            // by default
        cellClass :  'someCssClass'     
        cellRenderer : renderName()     // a function to render the column value (if anything other than a string), maybe an image or icon
     }        
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...