【问题标题】:Angular Grid ag-grid columnDefs Dynamically changeAngular Grid ag-grid columnDefs 动态变化
【发布时间】:2015-10-22 23:27:11
【问题描述】:

我对@9​​87654322@ 动态更改有疑问。这是我的网格选项:

$scope.gridOptions = {
  columnDefs: [],
  enableFilter: true,
  rowData: null,
  rowSelection: 'multiple',
  rowDeselection: true
};

当我从服务器检索数据时:

$scope.customColumns = [];

$http.post('/Home/GetProducts', { tableName: 'TABLE_PRODUCT' }).success(function (data) {
    angular.forEach(data.Columns, function (c) {
        $scope.customColumns.push(
            {
                headerName: c.Name,
                field: c.Value,
                width: c.Width
            }
        );
    });

    $scope.gridOptions.columnDefs = $scope.customColumns;

    $scope.gridOptions.rowData = data.Products;
    $scope.gridOptions.api.onNewRows();
}).error(function () {

});

注意:这里的 c 是来自服务器的列对象。

当动态生成列并将其分配给 $scope.gridOptions.columnDefs 时,会出现空白网格,但 $scope.customColumns 数组填充了正确生成的列对象。请帮助我是这个错误还是我做错了什么?

【问题讨论】:

标签: angularjs dynamic ag-grid


【解决方案1】:

在 ag-grid 中,gridOptions 中的列在网格初始化时使用一次。如果在初始化后更改列,则必须告诉网格。这是通过调用 gridOptions.api.setColumnDefs()

来完成的

ag-grid documentation here中提供了这个api方法的详细信息。

【讨论】:

  • 老实说,这是 ag-grid 设计中非常无棱角、无反应的部分。
  • 我们怎样才能在setColumnDefs之后得到columnDefs,而不用自己存储呢?我尝试使用 gridOptions.api.getColumnDef() 但失败了。
  • @aviit 迟到了,但是:您必须自己跟踪列更改和添加,没有等效的 api.getColumnDefs() 并且不会有一段时间:@987654322 @ 我已经提交了一个类似 api.getColumnDefs() 的功能请求,但谁知道什么时候会进入他们的开发管道。
【解决方案2】:

我认为这已经解决了。

我现在可以用最新的 angular 和 ag-grid 做这样的事情。请注意,我在这里使用的是 ngxs,但这仍然表明能够异步获取列定义,因为我正在根据从后端返回的数据的属性名称获取列定义,在这种情况下为 rowData。

首先,我从后端 API 获取行数据。 然后,当它被提取时,我在 Select for 列中执行操作,将标题从返回的数据映射到属性。

如果没有标题,数据将不会显示,一旦标题出现,它将重新绘制包含所有列定义和数据的网格。

<ag-grid-angular 
    style="width: 100%; height: 500px;" 
    class="ag-theme-balham"
    [rowData]="rowData$ | async" 
    [columnDefs]="columnsDefs$ | async"
    >
</ag-grid-angular>


export class AgGridComponent {
    @Select(MyState.getColumnDefs) public columnsDefs$!: Observable<ReadonlyArray<any>>;

    @Select(MyState.getRowData) public rowData$!: Observable<ReadonlyArray<any>>;
}

【讨论】:

    【解决方案3】:

    角度
    See demo

    查看下面的代码并注意ag-grid-angular 组件的 columnDefs 绑定到我们组件中的同名属性。

    <ag-grid-angular
        #agGrid
        style="width: 100%; height: 300px;"
        id="myGrid"
        class="ag-theme-alpine"
        [columnDefs]="columnDefs"
    

    app.component 中 columnDefs 属性的任何更新都将反映在我们的 ag-Grid 实例上。例如,看看我们如何在app.component的构造函数中设置初始列定义:

    constructor() {
        this.columnDefs = colDefsAthleteExcluded;
    }
    

    我们可以在我们的 ag-Grid 实例中添加或删除列,只需更新 columnDefs 绑定属性,传入一组新的列定义。

    • 以前不存在的列将被添加到 ag-Grid 实例中。

    • 未包含在新集合中的列将从 ag-Grid 实例中删除。

    请在“包括运动员栏”和“排除运动员栏”按钮的事件处理程序中查看下面的代码:

    // removes the athlete column
    onBtExcludeAthleteColumn() {
        this.columnDefs = colDefsAthleteExcluded;
    }
    
    // adds the athlete column
    onBtIncludeAthleteColumn() {
        this.columnDefs = colDefsAthleteIncluded;
    }
    

    要更新现有的列定义,我们首先调用 ag-Grid API 方法getColumnDefs() 来获取对网格当前列的引用。然后我们映射列,在更新我们的 columnDefs 绑定属性之前更改任何所需的属性。

    然后,ag-Grid 会将现有列与我们的 ag-Grid 实例中的列进行匹配,并更新已更改的列。

    请在“Set HeaderNames”和“Remove HeaderNames”按钮的事件处理程序中查看下面的代码:

    // sets each columns headerName property
    setHeaderNames() {
        var columnDefs = this.gridApi.getColumnDefs();
        columnDefs.forEach(function(colDef, index) {
            colDef.headerName = "C" + index;
        });
        this.columnDefs = columnDefs;
    }
    
    
    // clears each columns headerName property
    removeHeaderNames() {
        var columnDefs = this.gridApi.getColumnDefs();
        columnDefs.forEach(function(colDef, index) {
            colDef.headerName = undefined;
        });
        this.columnDefs = columnDefs;
    }
    

    反应
    See demo

    使用 React 时,我们可以选择以声明方式声明 ag-Grid 列。在上面的示例中,您将看到我们通过映射状态变量 columns 并为每个列定义返回一个 agGridColumn React 组件来创建 ag-Grid 列,同时传播道具:

    const App = () => {
        const [columns, setColumns] = useState(colDefsAthleteExcluded);
    
        return (
            {columns.map(column => (
                <AgGridColumn {...column} key={column.field} />
            ))}
    

    要添加或删除列,我们只需调用setColumns setState 方法,传入一组新的列定义。

    • 以前不存在的列将被添加到 ag-Grid 实例中。
    • 未包含在新集合中的列将从 ag-Grid 实例中删除。

    请在“包括运动员栏”和“排除运动员栏”按钮的事件处理程序中查看下面的代码:

    // removes the athlete column
    const onBtExcludeAthleteColumn = () => {
        setColumns(colDefsAthleteExcluded);
    };
    
    // adds the athlete column
    const onBtIncludeAthleteColumn = () => {
        setColumns(colDefsAthleteIncluded);
    };
    

    要更新现有的列定义,我们首先调用 ag-Grid API 方法getColumnDefs() 来获取对网格当前列的引用。然后我们映射列,在调用setColumns 之前更改任何所需的属性并更新我们的columns 状态变量。

    然后,ag-Grid 会将现有列与我们的 ag-Grid 实例中的列进行匹配,并更新已更改的列。

    请在“Set HeaderNames”和“Remove HeaderNames”按钮的事件处理程序中查看下面的代码:

    // sets each columns headerName property
    const setHeaderNames = () => {
        const newColumns = gridApi.getColumnDefs();
        newColumns.forEach((newColumn, index) => {
            newColumn.headerName = "C" + index;
        });
        setColumns(newColumns);
    };
    
    // clears each columns headerName property
    const removeHeaderNames = () => {
        const newColumns = gridApi.getColumnDefs();
        newColumns.forEach((newColumn, index) => {
            newColumn.headerName = undefined;
        });
        setColumns(newColumns);
    };
    

    Vue
    See demo

    您将在下面看到我们的 ag-grid-vue 组件的 columnDefs 绑定到我们组件中的同名属性。

    <ag-grid-vue
        style="width: 100%; height: 300px;"
        class="ag-theme-alpine"
        id="myGrid"
        :columnDefs="columnDefs"
    

    对 Vue 组件中 columnDefs 属性的任何更新都将反映在我们的 ag-Grid 实例中。例如,看看我们如何在beforeMount生命周期方法中设置初始列定义:

    beforeMount() { 
        this.columnDefs = colDefsAthleteExcluded;
    }
    

    要向我们的 ag-Grid 实例添加或删除列,我们更新 columnDefs 绑定属性,传入一组新的列定义。

    • 以前不存在的列将被添加到 ag-Grid 实例中。
    • 未包含在新集合中的列将从 ag-Grid 实例中删除。

    请在“包括运动员栏”和“排除运动员栏”按钮的事件处理程序中查看下面的代码:

    // removes the athlete column
    btnExcludeAthleteColumn() {
        this.columnDefs = colDefsAthleteExcluded;
    },  
    // adds the athlete column
    btnIncludeAthleteColumn() {
        this.columnDefs = colDefsAthleteIncluded;
    }
    

    要更新现有的列定义,我们首先调用 ag-Grid API 方法getColumnDefs() 来获取对网格当前列的引用。然后我们映射列,在更新我们的columnDefs 绑定属性之前更改任何所需的属性。

    然后,ag-Grid 会将现有列与我们的 ag-Grid 实例中的列进行匹配,并更新已更改的列。

    请在“Set HeaderNames”和“Remove HeaderNames”按钮的事件处理程序中查看下面的代码:

    // sets each columns headerName property
    setHeaderNames() {
        var columnDefs = this.gridApi.getColumnDefs();
        columnDefs.forEach(function(colDef, index) {
            colDef.headerName = "C" + index;
        });
        this.columnDefs = columnDefs;
    }
    
    
    // clears each columns headerName property
    removeHeaderNames() {
        var columnDefs = this.gridApi.getColumnDefs();
        columnDefs.forEach(function(colDef, index) {
            colDef.headerName = undefined;
        });
        this.columnDefs = columnDefs;
    }
    

    原版 JS.
    See demo.

    使用 vanilla JS 时,列定义不能绑定到我们应用程序中的属性,因为 JavaScript 没有内置的反应数据机制。相反,我们使用 ag-Grid API 方法 setColumnDefs() 来设置和更新我们的列。

    要向我们的 ag-Grid 实例添加或删除列,我们调用 setColumnDefs API,传入一组新的列定义。

    • 以前不存在的列将被添加到 ag-Grid 实例中。
    • 未包含在新集合中的列将从 ag-Grid 实例中删除。

    请在“包括运动员栏”和“排除运动员栏”按钮的事件处理程序中查看下面的代码:

    // removes athlete column
    function onBtExcludeAthleteColumn() {
        gridOptions.api.setColumnDefs(colDefsAthleteExcluded);
    }
    
    // adds athlete column
    function onBtIncludeAthleteColumn() {
        gridOptions.api.setColumnDefs(colDefsAthleteIncluded);
    }
    

    要更新现有的列定义,我们首先调用 ag-Grid API 方法getColumnDefs() 来获取对网格当前列的引用。然后我们映射列,在调用 setColumnDefs(colDefs) 之前更改任何所需的属性并传入更新的列。

    然后,ag-Grid 会将现有列与我们的 ag-Grid 实例中的列进行匹配,并更新已更改的列。

    请在“Set HeaderNames”和“Remove HeaderNames”按钮的事件处理程序中查看下面的代码:

    // sets each columns headerName property
    function setHeaderNames() {
        var columnDefs = gridOptions.api.getColumnDefs();
        columnDefs.forEach(function(colDef, index) {
            colDef.headerName = "C" + index;
        });
    gridOptions.api.setColumnDefs(columnDefs);
    }
    
    // clears each columns headerName property
    function removeHeaderNames() {
        var columnDefs = gridOptions.api.getColumnDefs();
        columnDefs.forEach(function(colDef, index) {
            colDef.headerName = undefined;
        });
        gridOptions.api.setColumnDefs(columnDefs);
    }
    

    阅读我们website 上的完整博客文章或查看我们的documentation,了解您可以使用 ag-Grid 实现的各种场景。

    艾哈迈德·加迪尔 |开发者@ag-Grid

    【讨论】:

    • 嘿@ahmedg94 这似乎在 React 中不起作用?我理解这个概念,使用 setState / useState 导致重新渲染,但在我的示例中,它不会重新渲染。我正在使用带有自定义单元格渲染器的企业 treeData,所以它有点复杂
    • 想通了。我想我们还得打电话给gridApi.setColumnDefs(colDefs)?我没有在你的文章中看到它
    • 这是我在 SO 上见过的最长的答案。将其提取到博客中可能是一个好主意。干杯。
    猜你喜欢
    • 2018-10-24
    • 2019-03-01
    • 1970-01-01
    • 2018-10-26
    • 2016-12-10
    • 2016-03-11
    • 2018-01-06
    • 2019-08-22
    • 2020-06-19
    相关资源
    最近更新 更多