AgGrid 选择单元格编辑器
Posted
技术标签:
【中文标题】AgGrid 选择单元格编辑器【英文标题】:AgGrid Select Cell Editor 【发布时间】:2021-08-09 08:53:19 【问题描述】:我正在使用 v8 角度 ag-grid。
this.columns = [
headerName: "XYZ", field:"XYZ",
editable: true ,cellEditor: "select",
cellEditorParams: values : [// list of values],
]
我想通过单击键盘导航来创建一个下拉选择(键盘上按下的字母应显示以该字母开头的值)。
【问题讨论】:
【参考方案1】:您可以为此使用自动完成功能。首先,您需要准备自己的 AutoComplete 组件。
AutoCompleteComponent.ts
import Component, AfterViewInit, ViewChild, ViewEncapsulation, ElementRef, HostListener from '@angular/core';
import ICellEditorAngularComp from 'ag-grid-angular';
@Component(
selector: 'auto-complete',
encapsulation: ViewEncapsulation.None,
template: `
<input #input
[(ngModel)]="inputValue"
(ngModelChange)="processDataInput($event)" >
<ag-grid-angular
[style.height]="gridHeight + 'px'"
[style.max-width]="gridWidth + 'px'"
class="ag-theme-balham"
[rowData]="rowData"
[columnDefs]="columnDefs"
[rowSelection]="rowSelection"
(gridReady)="onGridReady($event)"
[headerHeight]="headerHeight"
(rowClicked)="rowClicked($event)">
</ag-grid-angular>
`
)
export class AutoCompleteComponent implements ICellEditorAngularComp, AfterViewInit
// variables for agGrid
public params: any;
public gridApi: any;
public rowData: any;
public columnDefs: [];
public rowSelection: string = 'single';
public columnFilter: any;
// variables for component
public returnObject: boolean;
public cellValue: string;
public filteredRowData: any;
public inputValue: string;
public apiEndpoint: string;
public gridHeight: number = 175;
public gridWidth: number = 375;
public useApi: boolean;
public propertyName: string;
public isCanceled: boolean = true;
public selectedObject: any =
public headerHeight: number = 0;
private cellFocusIndex: number;
@ViewChild("input", static: false ) input: ElementRef;
showedColumn: any;
constructor()
// will be selected if there is a default value
ngAfterViewInit()
window.setTimeout(() =>
if (this.inputValue == this.cellValue)
this.input.nativeElement.select();
else
this.input.nativeElement.focus();
if (this.inputValue && !this.useApi) this.updateFilter();
)
// ICellEditorAngularComp functions
agInit(params: any): void
this.params = params;
if (!params.rowData)
this.apiEndpoint = params.apiEndpoint;
this.useApi = true;
this.rowData = []
else
this.rowData = params.rowData;
if (params.gridHeight) this.gridHeight = params.gridHeight;
if (params.gridWidth) this.gridWidth = params.gridWidth;
params.columnDefs.forEach((el: any) =>
if (typeof el.filter === "undefined")
el.filter = 'agTextColumnFilter'
);
this.columnDefs = params.columnDefs;
this.propertyName = params.propertyRendered;
this.showedColumn = params.showedColumn;
this.cellValue = params.data[this.propertyName];
this.returnObject = params.returnObject;
if (!params.charPress)
if (this.cellValue) this.inputValue = this.cellValue;
else
this.inputValue = params.charPress;
getValue(): any
if (!this.returnObject) return this.selectedObject[this.propertyName];
return this.selectedObject;
isPopup(): boolean
return true;
isCancelAfterEnd(): boolean
return this.isCanceled
// ag-Grid functions
onGridReady(params: any)
this.gridApi = params.api;
this.gridApi.sizeColumnsToFit();
this.columnFilter = this.gridApi.getFilterInstance(this.propertyName);
// component functions
// double clicked value will be selected and combobox will be closed.
rowClicked(params: any)
this.selectedObject = params.data;
this.isCanceled = false;
this.params.api.stopEditing();
// Board Event
@HostListener('keydown', ['$event'])
onKeydown(event: any)
event.stopPropagation();
if (event.key == "Escape")
this.params.api.stopEditing();
return false;
if (event.key == "Enter" || event.key == "Tab")
this.rowConfirmed();
return false;
if (event.key == "ArrowUp")
this.navigateGrid();
if (this.cellFocusIndex == 0 && this.gridApi.getFocusedCell().rowIndex == 0) //-- yukarı çıkmak istiyor
this.input.nativeElement.focus();
else
this.cellFocusIndex = this.gridApi.getFocusedCell().rowIndex;
return false;
if (event.key == "ArrowDown")
this.navigateGrid();
return false;
processDataInput(event: any)
this.updateFilter()
updateFilter()
this.columnFilter.setModel(
type: 'contains',
filter: this.inputValue,
);
this.columnFilter.onFilterChanged();
if (this.gridApi.getDisplayedRowAtIndex(0))
this.gridApi.getDisplayedRowAtIndex(0).setSelected(true);
this.gridApi.ensureIndexVisible(0, 'top');
else
this.gridApi.deselectAll();
// Enter Event Process
rowConfirmed()
if (this.gridApi.getSelectedRows()[0])
this.selectedObject = this.gridApi.getSelectedRows()[0];
this.isCanceled = false;
this.params.api.stopEditing();
// Arrow change event
// The data navigated on it is written to adjust its position on the screen with the arrow keys.
navigateGrid()
if (this.gridApi.getFocusedCell() == null || this.gridApi.getDisplayedRowAtIndex(this.gridApi.getFocusedCell().rowIndex) == null) // check if no cell has focus, or if focused cell is filtered
this.gridApi.setFocusedCell(this.gridApi.getDisplayedRowAtIndex(0).rowIndex, this.showedColumn != undefined ? this.showedColumn : this.propertyName);
this.gridApi.getDisplayedRowAtIndex(this.gridApi.getFocusedCell().rowIndex).setSelected(true);
else
this.gridApi.setFocusedCell(this.gridApi.getFocusedCell().rowIndex, this.showedColumn != undefined ? this.showedColumn : this.propertyName);
this.gridApi.getDisplayedRowAtIndex(this.gridApi.getFocusedCell().rowIndex).setSelected(true);
新创建的组件必须在模块中定义
custom.module.ts
import NgModule from '@angular/core';
import CommonModule from '@angular/common';
import AgGridModule from 'ag-grid-angular';
import AutoCompleteComponent from './auto-complete.component';
@NgModule(
declarations: [CustomComponent],
imports: [CommonModule,
AgGridModule.withComponents([AutoCompleteComponent])],
exports: [],
providers: []
)
export class CustomModule
我们的新组件现在可以使用了
在 custom.component.ts 中
frameworkComponents: any =
autoComplete: AutoCompleteComponent
;
columnsDef = [
headerName: 'XYZ,
field: 'xyz',
editable: true,
filter: 'agSetColumnFilter',
cellEditorSelector: function ()
return
component: 'autoComplete',
params:
propertyRendered: 'xyz',
returnObject: true,
showedColumn: 'xyz',
rowData: [xyz : '1',, desc : 'One', xyz :'2', desc : 'Two', xyz:'3', desc : 'Three'],
columnDefs: [
headerName: 'XYZ',
field: 'xyz',
filter: 'agTextColumnFilter',
suppressMenu: true,
valueFormatter: (event: any) =>
let data = event.data
return data.xyz + " - " + data.desc
,
headerName: 'DESC',
field: 'desc',
filter: 'agTextColumnFilter',
hide: true
]
,
comparator: this.customComparator,
valueGetter: (event: any) =>
const val = event.data.xyz;
return val.xyz+ " - " + val.desc;
]
在 custom.component.html 中
<ag-grid-angular #agGrid (gridReady)="onGridReady($event)"
(selectionChanged)="onSelectionChanged($event)"
[columnDefs]="columnDefs"
[frameworkComponents]="frameworkComponents"
[rowData]="rowData"
[suppressRowClickSelection]="true"
class="ag-theme-balham" >
</ag-grid-angular>
请尝试返回。当我在本地尝试时,我可以得到解决方案。
工作演示:https://stackblitz.com/edit/angular-ivy-ipvkac?file=src/app/app.component.ts
【讨论】:
你在 plunker 或 stackblitz 上有这个例子吗? stackblitz.com/edit/angular-ivy-ipvkac?file=src/app/… 这个例子运行失败 是的,它正在工作,但所需的功能是键盘导航。单元格以按字符开始渲染下拉选项,然后单击编辑即可开始(意味着单击时出现下拉菜单)【参考方案2】:我能够通过创建单元格渲染器而不是编辑器来实现所需 - 这有助于我通过单击获得下拉菜单并使用角度材料实现下拉菜单。
【讨论】:
您能分享一下您的解决方案吗?以上是关于AgGrid 选择单元格编辑器的主要内容,如果未能解决你的问题,请参考以下文章
如何使 JTable 单元格不可编辑但应该能够选择和复制当前单元格中的值