Ag-Grid - 保存列以备将来使用

Ag-Grid - Saving columns for future use

我正在为 angular1 使用 ag-grid(并且喜欢它),我希望我的用户能够重新组织列、更改排序以及所有内容,并且它会在刷新后保留。 它应该不是很难,除了列是循环的(包含指向它们自身的指针),因此我无法解析它们。

代码:

var columnDefsKey = "columnDefs["+$rootScope.page+"]";
var savedColumns = localStorage.getItem(columnDefsKey);
function saveColumnsState() {
    var currentCol = vm.gridOptions.columnApi.getAllColumns();
    if (!angular.equals(currentCol, savedColumns))
        try {
            localStorage.setItem(columnDefsKey, JSON.stringify(currentCol));
        } catch (ex) {
            log(ex);
            log(currentCol);
        }
}

并且:

onColumnEverythingChanged: saveColumnsState,
onColumnVisible: saveColumnsState,
onColumnPinned: saveColumnsState,
onColumnResized: saveColumnsState,
onColumnRowGroupChanged: saveColumnsState,
onColumnValueChanged: saveColumnsState,
onColumnMoved: saveColumnsState,
onColumnGroupOpened: saveColumnsState,

它每次都在 "try" 上失败: 类型错误:将循环结构转换为 JSON(…) [列、列、列、列、列、列、列、列、列、列]

我该怎么做? (保存列供以后使用)

如果我能做到这一点,我将能够在不编码的情况下创建多个视图。

你可以从下面更好地理解这个问题link

Chrome sendrequest error: TypeError: Converting circular structure to JSON

同时检查下面的参考资料

https://github.com/isaacs/json-stringify-safe

实现这一点的方法是构建我自己的列模型,我可以再次保存和解析,并且只保存必要的属性。

此方法存在 XSS 漏洞,因为我正在评估函数,但它是一个可行的解决方案。

columnsApi: {
    key: null,
    grid: null,
    newColumnModel: {
        headerName: "",
        width: 200,
        valueGetter: "",
        filter: 'text',
        aggFunc: 'none',
        filterParams: {apply: true}
    },
    setKey: function (key) {
        this.key = key;
    },
    setGrid: function (grid) {
        this.grid = grid;
    },
    format: function (columns) {
        var format = [];
        angular.forEach(columns, function (col) {
            var colDef = {
                width: col.actualWidth,
                pinned: col.pinned,
                hide: !col.visible
            };
            format.push(angular.extend(col.colDef, colDef));
        });
        return format;
    },
    getIDs: function (columns) {
        var ids = [];
        angular.forEach(columns, function (col) {
            ids.push(col.colId);
        });
        return ids;
    },
    stringify: function (columns) {
        return JSON.stringify(columns, function (key, value) {
            if (typeof value === "function")
                return "/Function(" + value.toString() + ")/";
            return value;
        });
    },
    parse: function (string) {
        return JSON.parse(string, function (key, value) {
            if (typeof value === "string" &&
                value.startsWith("/Function(") &&
                value.endsWith(")/")) {
                value = value.substring(10, value.length - 2);
                return eval("(" + value + ")");
            }
            return value;
        });
    },
    add: function (column) {
        if (this.grid === null) {
            console.error("Assertion error: grid must not be null");
            return;
        }

        if(column.aggFunc == 'none')
            column.aggFunc = undefined;
        var groups = this.get().groups;
        var newColumns = this.format(getGridColumns(this.grid));
        newColumns.push(column);
        this.grid.api.setColumnDefs(newColumns);
        this.setGroups(groups);
    },
    save: function () {
        var self = this;
        if (this.key === null) {
            console.error("Assertion error: key must not be null");
            return;
        }
        if (this.grid === null) {
            console.error("Assertion error: grid must not be null");
            return;
        }

        var savedOptions = {
            columns: self.format(getGridColumns(self.grid)),
            groups: self.getIDs(self.grid.columnApi.getRowGroupColumns()),
            sorting: self.grid.api.getSortModel(),
            filter: self.grid.api.getFilterModel()
        };

        localStorage.setItem(this.key, this.stringify(savedOptions));
    },
    // Get function uses "eval" - XSS vulnerable.
    get: function () {
        if (this.key === null) {
            console.error("Assertion error: key must not be null");
            return;
        }
        var options = localStorage.getItem(this.key);
        if (options)
            options = this.parse(options);

        return options;
    },
    remove: function (field) {
        if (this.grid === null) {
            console.error("Assertion error: grid must not be null");
            return;
        }
        var newColumns = this.format(getGridColumns(this.grid));
        angular.forEach(newColumns, function (col, key) {
            if (col.field == field)
                newColumns.splice(key, 1);
        });
        this.grid.api.setColumnDefs(newColumns);
    },
    setGroups: function (groups) {
        var self = this;
        angular.forEach(groups, function (id) {
            angular.forEach(getGridColumns(self.grid), function (col) {
                if (col.colId == id)
                    self.grid.columnApi.addRowGroupColumn(col);
            });
        });
    }
}

我相信这个解决方案是为 Ag-Grid 5 编写的,因此我不确定它是否仍然有效。