You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular-Slickgrid子对象单/多选编辑器返回值格式异常求助

问题:Angular-Slickgrid子对象字段行内编辑返回对象而非具体值

问题描述

处理Angular-Slickgrid中子对象(复杂对象)的SingleSelect和Multiselect字段行内编辑时,编辑器返回对象格式的值;但处理简单对象时,会返回选中的具体值。

  • 子对象(复杂对象)当前返回值:包含label、value的完整对象
  • 期望返回值:选中项的具体值(与简单对象的返回格式一致)

相关代码与配置

列定义

{
    id: this.tableColumnInfo[this.__parentobj01$tableName]['pfm775773_gender_11035840']['id'],
    nameKey: lodash.escape(this.translateService.instant(this.tableColumnInfo[this.__parentobj01$tableName]['pfm775773_gender_11035840']['label'])),
    field: this.tableColumnInfo[this.__parentobj01$tableName]['pfm775773_gender_11035840']['prop'],
    toolTip: this.slickgridUtils.convertSplCharToEntities(this.translateService.instant(this.tableColumnInfo[this.__parentobj01$tableName]['pfm775773_gender_11035840']['label']), 'fromEntity'),
    sortable: true,
    type: FieldType.string,
    sortComparer: cspfmSlickgridSortComparer.StringSortComparer,

    exportCustomFormatter: CspfmDataExportFormatter,
    exportWithFormatter: true,

    formatter: CspfmDataFormatter,
    queryField: this.tableColumnInfo[this.__parentobj01$tableName]['pfm775773_gender_11035840']['prop'] + appConstant['customFieldSuffix']['slickgrid'],
    filterable: true,
    filter: {
        collection: this.slickgridUtils.getLabelValue(this.tableColumnInfo[this.__parentobj01$tableName]['pfm775773_gender_11035840']['mappingDetails']),
        enableTranslateLabel: true,
        model: Filters.multipleSelect
    },
    grouping: <cspfmDataGrouping> {
        getter: (data) => {
            return this.slickgridUtils.getter(data, this.tableColumnInfo[this.__parentobj01$tableName]['pfm775773_gender_11035840'])
        },
        formatter: (groupingFormatterItem: GroupingFormatterItem) => {
            return this.slickgridUtils.formatter(groupingFormatterItem, this.tableColumnInfo[this.__parentobj01$tableName]['pfm775773_gender_11035840']['label'])
        },
        params: {
            id: this.tableColumnInfo[this.__parentobj01$tableName]['pfm775773_gender_11035840']['id']
        },
        collapsed: false
    },
    cssClass: 'left-align cs-slickgrid-inline-edit-pointer',

    editor: {
        model: Editors.singleSelect,
        collection: this.slickgridUtils.getKeyValue(this.tableColumnInfo[this.__parentobj01$tableName]['pfm775773_gender_11035840']['mappingDetails']),
        enableTranslateLabel: true,
    },
    params: {
        isHiddenEnabled: 'N',
        columnWidth: 100,
        required: false,
        pipe: this.cspfmDataDisplay,
        fieldInfo: this.tableColumnInfo[this.__parentobj01$tableName]['pfm775773_gender_11035840'],
        layoutId: this.layoutId
    }
}

TableColumn 配置信息

"pfm775773_gender_11035840": {
    "child": {
        "id": "gender",
        "label": "Inline_Edit_List01_WEB_List.Element.parentobj01_DUMMY$$childobj01_parentobj$$gender.gender",
        "fieldName": "gender",
        "prop": "gender",
        "fieldType": "RADIO",
        "objectName": "childobj01",
        "elementid": 11035840,
        "traversalpath": "parentobj01_DUMMY$$childobj01_parentobj$$gender",
        "child": "",
        "dateFormat": "",
        "mappingDetails": this.gender_1717578_11035840,
        "currencyDetails": "",
        "boxStyle": "",
        "valueStyle": ""
    },
    "id": "pfm775773s_0_gender",
    "prop": "pfm775773s.0.gender",
    "label": "Inline_Edit_List01_WEB_List.Element.parentobj01_DUMMY$$childobj01_parentobj$$gender.gender",
    "elementid": 11035840,
    "mappingDetails": this.gender_1717578_11035840,
    "traversalpath": "parentobj01_DUMMY$$childobj01_parentobj$$gender",
    "dateFormat": "",
    "currencyDetails": "",
    "fieldName": "pfm775773s",
    "fieldType": "MASTERDETAIL",
    "objectName": "childobj01"
}

selectEditor.js 核心方法

get currentValues() {
    var _a, _b, _c, _d, _e;
    const elmValue = (_a = this.$editorElm) === null || _a === void 0 ? void 0 : _a.val();
    // collection of strings, just return the filtered string that are equals
    if (this.collection.every(x => typeof x === 'string')) {
        return this.collection.filter(c => elmValue.indexOf(c === null || c === void 0 ? void 0 : c.toString()) !== -1);
    }
    // collection of label/value pair
    const separatorBetweenLabels = (_c = (_b = this.collectionOptions) === null || _b === void 0 ? void 0 : _b.separatorBetweenTextLabels) !== null && _c !== void 0 ? _c : '';
    const isIncludingPrefixSuffix = (_e = (_d = this.collectionOptions) === null || _d === void 0 ? void 0 : _d.includePrefixSuffixToSelectedValues) !== null && _e !== void 0 ? _e : false;
    return this.collection
        .filter(c => { var _a; return elmValue.indexOf(c.hasOwnProperty(this.valueName) && ((_a = c[this.valueName]) === null || _a === void 0 ? void 0 : _a.toString())) !== -1; })
        .map(c => {
        var _a, _b, _c, _d;
        const labelText = c[this.valueName];
        let prefixText = c[this.labelPrefixName] || '';
        let suffixText = c[this.labelSuffixName] || '';
        // when it's a complex object, then pull the object name only, e.g.: "user.firstName" => "user"
        const fieldName = (_b = (_a = this.columnDef) === null || _a === void 0 ? void 0 : _a.field) !== null && _b !== void 0 ? _b : '';
        // is the field a complex object, "address.streetNumber"
        const isComplexObject = (fieldName === null || fieldName === void 0 ? void 0 : fieldName.indexOf('.')) > 0;
        const serializeComplexValueFormat = (_d = (_c = this.columnEditor) === null || _c === void 0 ? void 0 : _c.serializeComplexValueFormat) !== null && _d !== void 0 ? _d : 'object';
        if (isComplexObject && typeof c === 'object' && serializeComplexValueFormat === 'object') {
            return c;
        }
        // also translate prefix/suffix if enableTranslateLabel is true and text is a string
        prefixText = (this.enableTranslateLabel && this._translaterService && prefixText && typeof prefixText === 'string') ? this._translaterService.translate(prefixText || ' ') : prefixText;
        suffixText = (this.enableTranslateLabel && this._translaterService && suffixText && typeof suffixText === 'string') ? this._translaterService.translate(suffixText || ' ') : suffixText;
        if (isIncludingPrefixSuffix) {
            const tmpOptionArray = [prefixText, labelText, suffixText].filter((text) => text); // add to a temp array for joining purpose and filter out empty text
            return tmpOptionArray.join(separatorBetweenLabels);
        }
        return labelText;
    });
}
/**
 * The current selected values (single select) from the collection
 */
get currentValue() {
    var _a, _b, _c, _d, _e, _f;
    const elmValue = this.$editorElm.val();
    const fieldName = this.columnDef && this.columnDef.field;
    if (fieldName !== undefined) {
        // collection of strings, just return the filtered string that are equals
        if (this.collection.every(x => typeof x === 'string')) {
            return findOrDefault(this.collection, (c) => { var _a; return ((_a = c === null || c === void 0 ? void 0 : c.toString) === null || _a === void 0 ? void 0 : _a.call(c)) === elmValue; });
        }
        // collection of label/value pair
        const separatorBetweenLabels = (_b = (_a = this.collectionOptions) === null || _a === void 0 ? void 0 : _a.separatorBetweenTextLabels) !== null && _b !== void 0 ? _b : '';
        const isIncludingPrefixSuffix = (_d = (_c = this.collectionOptions) === null || _c === void 0 ? void 0 : _c.includePrefixSuffixToSelectedValues) !== null && _d !== void 0 ? _d : false;
        const itemFound = findOrDefault(this.collection, (c) => { var _a; return c.hasOwnProperty(this.valueName) && ((_a = c[this.valueName]) === null || _a === void 0 ? void 0 : _a.toString()) === elmValue; });
        // is the field a complex object, "address.streetNumber"
        const isComplexObject = (fieldName === null || fieldName === void 0 ? void 0 : fieldName.indexOf('.')) > 0;
        const serializeComplexValueFormat = (_f = (_e = this.columnEditor) === null || _e === void 0 ? void 0 : _e.serializeComplexValueFormat) !== null && _f !== void 0 ? _f : 'object';
        if (isComplexObject && typeof itemFound === 'object' && serializeComplexValueFormat === 'object') {
            return itemFound;
        }
        else if (itemFound && itemFound.hasOwnProperty(this.valueName)) {
            const labelText = itemFound[this.valueName];
            if (isIncludingPrefixSuffix) {
                let prefixText = itemFound[this.labelPrefixName] || '';
                let suffixText = itemFound[this.labelSuffixName] || '';
                // also translate prefix/suffix if enableTranslateLabel is true and text is a string
                prefixText = (this.enableTranslateLabel && this._translaterService && prefixText && typeof prefixText === 'string') ? this._translaterService.translate(prefixText || ' ') : prefixText;
                suffixText = (this.enableTranslateLabel && this._translaterService && suffixText && typeof suffixText === 'string') ? this._translaterService.translate(suffixText || ' ') : suffixText;
                // add to a temp array for joining purpose and filter out empty text
                const tmpOptionArray = [prefixText, labelText, suffixText].filter((text) => text);
                return tmpOptionArray.join(separatorBetweenLabels);
            }
            return labelText;
        }
    }
    return '';
}

环境版本

  • Angular: 13.3.9
  • Angular-Slickgrid: 4.3.1
  • slickgrid-universal: 1.4.0
  • TypeScript: 4.6.4
  • 操作系统: Windows 10
  • Node: 14.18.3
  • NPM: 6.14.8

解决方案

从selectEditor.js的代码逻辑可知,当字段是复杂对象(字段名包含.)且serializeComplexValueFormat为object时,会直接返回选中的对象。要让子对象字段返回具体值,有两种实现方式:

方式1:修改列定义的editor配置(推荐)

在目标列的editor属性中添加serializeComplexValueFormat: 'value',强制编辑器返回具体值而非对象:

editor: {
    model: Editors.singleSelect,
    collection: this.slickgridUtils.getKeyValue(this.tableColumnInfo[this.__parentobj01$tableName]['pfm775773_gender_11035840']['mappingDetails']),
    enableTranslateLabel: true,
    serializeComplexValueFormat: 'value' // 添加该行配置
},

方式2:修改selectEditor.js的全局逻辑

若需全局生效,可修改selectEditor.js中判断复杂对象的逻辑,将serializeComplexValueFormat的默认值改为'value',或直接移除复杂对象时返回对象的分支:

// 在currentValues和currentValue方法中,注释或删除以下判断分支
// if (isComplexObject && typeof c === 'object' && serializeComplexValueFormat === 'object') {
//     return c;
// }

内容的提问来源于stack exchange,提问作者Surya Kesavan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 12:30:45