0

我正在使用 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,

每次“尝试”都会失败:TypeError: Converting circular structure to JSON(…) [Column, Column, Column, Column, Column, Column, Column, Column, Column, Column]

我怎样才能做到这一点?(保存列以备后用)

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

4

2 回答 2

2

您可以从以下链接更好地理解该问题

Chrome sendrequest 错误:TypeError:将循环结构转换为 JSON

另请检查以下参考

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

于 2016-04-08T09:08:25.873 回答
0

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

这种方法很容易受到 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 编写的,因此我不确定它是否仍然有效。

于 2017-01-31T17:29:05.650 回答