如何将 agSelectCellEditor 用于 Angular 网格中来自数据库的下拉值
How to use agSelectCellEditor for dropdown values coming from database in Angular Grid
我在 Angular 8 中使用 refData 和 agSelectCellEditor 来显示编辑时的下拉值。我参考以下 link 来解决我的问题:-
https://www.ag-grid.com/javascript-grid-reference-data/
但是下拉列表数据是通过 HTTP GET 查询从数据库中获取的。我在 agGrid 中使用 "cellEditorParams",其中包含方法 "extractValues()",如下所示。问题是该方法在数据来自数据库之前运行,这导致空白数据。如何解决这个问题?
理想的下拉列表应包含 "Yes/No" 的值。当我在顶部使用静态列表声明 "objCategoryMappings" 时,它工作正常。是否有任何限制,例如 "refData" 不能使用数据库中的动态列表?如果是这样,那么替代方案是什么?
请参考下面的代码。为简单起见,我在 subscribe 方法中静态设置了 "Yes/No" 。在实际情况下,我会使用 "objCategoryMappings" 来存储数据库中的值。
HTML
<ag-grid-angular class="ag-theme-balham" [gridOptions]="categoryGridOptions"
[rowData]="categoryRowData" [columnDefs]="categoryColDef"
(gridReady)="onGridReady($event)">
</ag-grid-angular>
TS 文件
export class CategoryComponent{
categoryRowData: any[];
objCategoryMappings = {};
constructor() {
this.getAllCategories();
}
getAllCategories()
{
this.categoryCommonService.getEntityData('getallcatgories')
.subscribe((rowData) => {
this.categoryRowData = rowData;
this.objCategoryMappings["f"] = "No";
this.objCategoryMappings["t"] = "Yes";
},
(error) => { alert(error) });
}
categoryColDef = [
{
headerName: 'Category Name', field: 'CategoryName',
cellEditor: 'agLargeTextCellEditor',
cellEditorParams: {
maxLength: '50',
cols: '20',
rows: '1'
}
},
{
headerName: 'Is Subcategory', field: 'IsSubcategory', //Values coming from db as "f" and "t"
cellEditor: 'agSelectCellEditor',
cellEditorParams: {
values: this.extractValues(this.objCategoryMappings),
},
refData: this.objCategoryMappings,
}];
extractValues(mappings) {
return Object.keys(mappings);
}
}
您可以使用 ngIf
指令控制 ag-grid
何时需要数据。
<ag-grid-angular
*ngIf="categoryRowData"
class="ag-theme-balham"
[gridOptions]="categoryGridOptions"
[rowData]="categoryRowData"
[columnDefs]="categoryColDef"
(gridReady)="onGridReady($event)"
>
</ag-grid-angular>
这将延迟 ag-grid
组件的呈现,直到数据可用
为什么要在获取网格行数据后构建 objCategoryMappings 对象?如我所见,它是静态的,您不需要 api 响应来构建它。
如果您想保留此逻辑,那么即使是列定义也应该在 api 响应之后完成,因为它需要 objCategoryMappings 数据,而该数据目前在定义时未定义:
export class CategoryComponent{
categoryRowData: any[];
objCategoryMappings = {};
categoryColDef ;
constructor() {
this.getAllCategories();
}
getAllCategories()
{
this.categoryCommonService.getEntityData('getallcatgories')
.subscribe((rowData) => {
this.categoryRowData = rowData;
this.objCategoryMappings["f"] = "No";
this.objCategoryMappings["t"] = "Yes";
this.createColumnsDefinition() ;
},
(error) => { alert(error) });
}
createColumnsDefinition(){
this.categoryColDef = [
{
headerName: 'Category Name', field: 'CategoryName',
cellEditor: 'agLargeTextCellEditor',
cellEditorParams: {
maxLength: '50',
cols: '20',
rows: '1'
}
},
{
headerName: 'Is Subcategory', field: 'IsSubcategory', //Values coming from db as "f" and "t"
cellEditor: 'agSelectCellEditor',
cellEditorParams: {
values: this.extractValues(this.objCategoryMappings),
},
refData: this.objCategoryMappings,
}];
...
}
在您的 html 中,您需要等待数据接收才能呈现网格,如 c_ogoo 所说:
<ag-grid-angular
*ngIf="categoryColDef"
class="ag-theme-balham"
[gridOptions]="categoryGridOptions"
[rowData]="categoryRowData"
[columnDefs]="categoryColDef"
(gridReady)="onGridReady($event)"
>
</ag-grid-angular>
另一种解决方案。与最佳答案不同,您不需要在数据接收到应用程序时创建 categoryColDef。您可以更早地创建它,并且只对 objCategoryMappings 进行更改。此实现所做的是在新数据从数据库或某处接收到应用程序时从 objCategoryMappings 中删除现有元素。当然,您也可以使用 push() 方法添加新数据,但问题是每当新数据接收到应用程序时,数组中的旧元素都不会被删除;因此,新数据被添加到已有旧数据的数组中。我在 Firebase 中经历过这种情况。我认为此解决方案可以轻松管理代码。
objCategoryMappings = [];
this.categoryCommonService.getEntityData('getallcatgories')
.subscribe((rowData) => {
this.objCategoryMappings.length = 0;
this.objCategoryMappings.push(...rowData);
});
cellEditor: 'agSelectCellEditor', cellEditorParams: { values: objCategoryMappings}
另一种解决方案。在这个解决方案中,它假设rowData和objCategoryMappings的数据都在同一个位置,因此你可以比较相同位置的元素,看是否有新的变化。如果有,则在 objCategoryMappings 中进行更改,而不是替换所有值。这可能是一个非常有效的解决方案。 (与第一个不同,我没有测试这个解决方案)
objCategoryMappings = [];
this.categoryCommonService.getEntityData('getallcatgories')
.subscribe((rowData) => {
this.assign(rowData);
});
function assign(rowData){
for(var i=0; i<rowData.length; i++) {
if (rowData[i] != objCategoryMappings[i]) {
objCategoryMappings[i] = rowData[i];
}
}
}
cellEditor: 'agSelectCellEditor', cellEditorParams: { values: objCategoryMappings}
You can set the length property to truncate an array at any time.
我在 Angular 8 中使用 refData 和 agSelectCellEditor 来显示编辑时的下拉值。我参考以下 link 来解决我的问题:-
https://www.ag-grid.com/javascript-grid-reference-data/
但是下拉列表数据是通过 HTTP GET 查询从数据库中获取的。我在 agGrid 中使用 "cellEditorParams",其中包含方法 "extractValues()",如下所示。问题是该方法在数据来自数据库之前运行,这导致空白数据。如何解决这个问题?
理想的下拉列表应包含 "Yes/No" 的值。当我在顶部使用静态列表声明 "objCategoryMappings" 时,它工作正常。是否有任何限制,例如 "refData" 不能使用数据库中的动态列表?如果是这样,那么替代方案是什么?
请参考下面的代码。为简单起见,我在 subscribe 方法中静态设置了 "Yes/No" 。在实际情况下,我会使用 "objCategoryMappings" 来存储数据库中的值。
HTML
<ag-grid-angular class="ag-theme-balham" [gridOptions]="categoryGridOptions"
[rowData]="categoryRowData" [columnDefs]="categoryColDef"
(gridReady)="onGridReady($event)">
</ag-grid-angular>
TS 文件
export class CategoryComponent{
categoryRowData: any[];
objCategoryMappings = {};
constructor() {
this.getAllCategories();
}
getAllCategories()
{
this.categoryCommonService.getEntityData('getallcatgories')
.subscribe((rowData) => {
this.categoryRowData = rowData;
this.objCategoryMappings["f"] = "No";
this.objCategoryMappings["t"] = "Yes";
},
(error) => { alert(error) });
}
categoryColDef = [
{
headerName: 'Category Name', field: 'CategoryName',
cellEditor: 'agLargeTextCellEditor',
cellEditorParams: {
maxLength: '50',
cols: '20',
rows: '1'
}
},
{
headerName: 'Is Subcategory', field: 'IsSubcategory', //Values coming from db as "f" and "t"
cellEditor: 'agSelectCellEditor',
cellEditorParams: {
values: this.extractValues(this.objCategoryMappings),
},
refData: this.objCategoryMappings,
}];
extractValues(mappings) {
return Object.keys(mappings);
}
}
您可以使用 ngIf
指令控制 ag-grid
何时需要数据。
<ag-grid-angular
*ngIf="categoryRowData"
class="ag-theme-balham"
[gridOptions]="categoryGridOptions"
[rowData]="categoryRowData"
[columnDefs]="categoryColDef"
(gridReady)="onGridReady($event)"
>
</ag-grid-angular>
这将延迟 ag-grid
组件的呈现,直到数据可用
为什么要在获取网格行数据后构建 objCategoryMappings 对象?如我所见,它是静态的,您不需要 api 响应来构建它。
如果您想保留此逻辑,那么即使是列定义也应该在 api 响应之后完成,因为它需要 objCategoryMappings 数据,而该数据目前在定义时未定义:
export class CategoryComponent{
categoryRowData: any[];
objCategoryMappings = {};
categoryColDef ;
constructor() {
this.getAllCategories();
}
getAllCategories()
{
this.categoryCommonService.getEntityData('getallcatgories')
.subscribe((rowData) => {
this.categoryRowData = rowData;
this.objCategoryMappings["f"] = "No";
this.objCategoryMappings["t"] = "Yes";
this.createColumnsDefinition() ;
},
(error) => { alert(error) });
}
createColumnsDefinition(){
this.categoryColDef = [
{
headerName: 'Category Name', field: 'CategoryName',
cellEditor: 'agLargeTextCellEditor',
cellEditorParams: {
maxLength: '50',
cols: '20',
rows: '1'
}
},
{
headerName: 'Is Subcategory', field: 'IsSubcategory', //Values coming from db as "f" and "t"
cellEditor: 'agSelectCellEditor',
cellEditorParams: {
values: this.extractValues(this.objCategoryMappings),
},
refData: this.objCategoryMappings,
}];
...
}
在您的 html 中,您需要等待数据接收才能呈现网格,如 c_ogoo 所说:
<ag-grid-angular
*ngIf="categoryColDef"
class="ag-theme-balham"
[gridOptions]="categoryGridOptions"
[rowData]="categoryRowData"
[columnDefs]="categoryColDef"
(gridReady)="onGridReady($event)"
>
</ag-grid-angular>
另一种解决方案。与最佳答案不同,您不需要在数据接收到应用程序时创建 categoryColDef。您可以更早地创建它,并且只对 objCategoryMappings 进行更改。此实现所做的是在新数据从数据库或某处接收到应用程序时从 objCategoryMappings 中删除现有元素。当然,您也可以使用 push() 方法添加新数据,但问题是每当新数据接收到应用程序时,数组中的旧元素都不会被删除;因此,新数据被添加到已有旧数据的数组中。我在 Firebase 中经历过这种情况。我认为此解决方案可以轻松管理代码。
objCategoryMappings = [];
this.categoryCommonService.getEntityData('getallcatgories')
.subscribe((rowData) => {
this.objCategoryMappings.length = 0;
this.objCategoryMappings.push(...rowData);
});
cellEditor: 'agSelectCellEditor', cellEditorParams: { values: objCategoryMappings}
另一种解决方案。在这个解决方案中,它假设rowData和objCategoryMappings的数据都在同一个位置,因此你可以比较相同位置的元素,看是否有新的变化。如果有,则在 objCategoryMappings 中进行更改,而不是替换所有值。这可能是一个非常有效的解决方案。 (与第一个不同,我没有测试这个解决方案)
objCategoryMappings = [];
this.categoryCommonService.getEntityData('getallcatgories')
.subscribe((rowData) => {
this.assign(rowData);
});
function assign(rowData){
for(var i=0; i<rowData.length; i++) {
if (rowData[i] != objCategoryMappings[i]) {
objCategoryMappings[i] = rowData[i];
}
}
}
cellEditor: 'agSelectCellEditor', cellEditorParams: { values: objCategoryMappings}
You can set the length property to truncate an array at any time.