如何将agSelectCellEditor用于来自Angular Grid中数据库的下拉值

时间:2019-12-13 02:49:21

标签: typescript dropdown angular8 ag-grid-angular

我在Angular 8中使用refData和agSelectCellEditor在编辑时显示下拉值。我指的是以下链接来解决我的问题:-

https://www.ag-grid.com/javascript-grid-reference-data/

但是下拉列表数据是通过HTTP GET查询来自数据库的。我正在agGrid中使用“ cellEditorParams”,其中包含方法“ extractValues()”,如下所示。问题在于该方法在数据来自数据库之前运行,并导致生成空白数据。该如何解决呢?

理想情况下,下拉列表中的值应为“是/否”。当我在静态列表的顶部声明“ objCategoryMappings”时,它工作正常。是否有类似“ refData”的限制不适用于数据库中的动态列表?如果是这样,那有什么选择呢?

enter image description here

请参考下面的代码。为简单起见,我在subscribe方法中静态设置了“是/否”。在实际情况下,我将使用“ 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);
    }

}

3 个答案:

答案 0 :(得分:1)

为什么要在获取网格行数据之后构建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>

答案 1 :(得分:0)

您可以使用ag-grid指令来控制ngIf何时需要数据。

<ag-grid-angular
  *ngIf="categoryRowData" 
  class="ag-theme-balham" 
  [gridOptions]="categoryGridOptions"
  [rowData]="categoryRowData" 
  [columnDefs]="categoryColDef"  
  (gridReady)="onGridReady($event)"
>
</ag-grid-angular>

这将延迟ag-grid组件的渲染,直到数据可用为止

答案 2 :(得分:0)

另一种解决方案。与最佳答案不同,当数据接收到应用程序时,您不需要创建 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.