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

在自定义Store中使用PortfolioItem/Feature模型遇格式问题求助

问题描述

我正在做一个特性(非用户故事)及其依赖关系的概览功能,流程是:

  1. 拉取按版本过滤的WSAPI Store
  2. 获取前置与后置集合来展示对应值

原本想直接把这个WSAPI Store用在网格里,但执行onScopeChange(版本过滤生效)时,网格渲染会早于前置/后置集合加载完成,所以改用了custom.store绑定到网格,这部分操作是正常的。

但现在遇到个问题:我需要自己处理大部分网格格式化,已经把自定义Store的model设置为PortfolioItem/Feature,本来期望网格能自动应用该模型的格式化,但并没有生效。用WSAPI Store的时候,Release和State字段能正常格式化,换成自定义Store后这两个字段就显示异常了。

相关代码如下:

自定义Store代码

_getViewStore: function () { 
    var me = this; 
    /* Extract data from featureStore */ 
    var records = me.myFeatureStore.getRecords(); 
    /* Create new, update, store for adding into grid */ 
    if (!me.myViewStore) { 
        me.myViewStore = Ext.create('Rally.data.custom.Store', { 
            model: 'PortfolioItem/Feature', 
            data: records, 
        }); 
    } else { 
        me.myViewStore.removeAll(); 
        me.myViewStore.add(records); 
    } 
}

网格代码

_createGrid: function () { 
    var me = this; 
    me.myGrid = Ext.create('Ext.Container', { 
        items: [{ 
            xtype: 'rallygrid', 
            store: me.myViewStore, 
            columnCfgs: [{ 
                xtype: 'gridcolumn', 
                align: 'left', 
                tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate'), 
                text: 'Predecessors', 
                dataIndex: 'Predecessors', 
                width: 200, 
                renderer: function (value, metaData, record) { 
                    var mFieldOutputPre = ''; 
                    var records = record.predecessorStore.getRecords(); 
                    _.each(records, function (feature) { 
                        mFieldOutputPre += Rally.nav.DetailLink.getLink({ 
                            record: feature, 
                            text: feature.get('FormattedID'), 
                            showTooltip: true 
                        }); 
                        // Add the feature name and a line break. 
                        mFieldOutputPre += ' - ' + feature.get('Name') + '<br>'; 
                    }); 
                    return mFieldOutputPre; 
                }, 
            }, { 
                text: 'FormattedID', 
                dataIndex: 'FormattedID', 
                xtype: 'templatecolumn', 
                tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate') 
            }, { 
                text: 'Name', 
                dataIndex: 'Name', 
                flex: 1 
            }, { 
                text: 'Release', 
                dataIndex: 'Release', 
                flex: 1 
            }, { 
                text: 'State', 
                dataIndex: 'State', 
                flex: 1 
            }, { 
                // Column 'Successors' 
                xtype: 'templatecolumn', 
                align: 'left', 
                tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate'), 
                text: 'Successors', 
                dataIndex: 'Successors', 
                width: 200, 
                renderer: function (value, metaData, record) { 
                    var mFieldOutputSuc = ''; 
                    var records = record.successorStore.getRecords(); 
                    _.each(records, function (feature) { 
                        mFieldOutputSuc += Rally.nav.DetailLink.getLink({ 
                            record: feature, 
                            text: feature.get('FormattedID'), 
                            showTooltip: true 
                        }); 
                        // Add the feature name and a line break. 
                        mFieldOutputSuc += ' - ' + feature.get('Name') + '<br>'; 
                    }); 
                    return mFieldOutputSuc; 
                }, 
            }] 
        }], 
        renderTo: Ext.getBody() 
    }); 
    me.add(me.myGrid); 
}

想请教下:这种场景下能不能让自定义Store应用PortfolioItem/Feature模型的格式化?如果可以的话,我哪里操作错了?


解决方案分析

首先明确:是可以让自定义Store应用模型的自动格式化的,你的问题出在自定义Store初始化和数据传递的细节上,下面给你拆解问题和修复方案:

1. 自定义Store的data参数问题

你直接把me.myFeatureStore.getRecords()拿到的记录丢给自定义Store的data属性,这里有个坑:WSAPI Store返回的是Rally数据模型实例,但Rally.data.custom.Store在接收data的时候,默认会把这些实例转成普通的JSON对象,丢失了模型关联的格式化逻辑、getter方法等。

这就是为什么Release和State字段显示异常——原来的WSAPI记录会通过模型的格式化器处理这些关联对象(比如Release会显示名称+链接,State会显示对应状态的样式),但转成普通对象后,这些信息只剩下原始的ref或者ID,自然没法正确渲染。

2. 修复方案:让自定义Store保留模型实例

你需要给自定义Store加上dataType: 'records'配置,告诉它直接接收并保留Rally模型实例,而不是转成JSON:

me.myViewStore = Ext.create('Rally.data.custom.Store', {
    model: 'PortfolioItem/Feature',
    data: records,
    dataType: 'records' // 关键配置,保留原始记录实例
});

加上这个配置后,自定义Store里的记录就和WSAPI Store里的一样,是完整的模型实例,网格就能自动调用模型对应的格式化器来处理Release、State这些字段了。

3. 额外注意点:前置/后置集合的加载时机

你之前遇到的网格渲染早于前置/后置集合加载的问题,在改用自定义Store后,要确保me.myFeatureStore里的所有记录的predecessorStore和successorStore都已经加载完成,再把记录添加到自定义Store里。否则网格里的前置/后置列可能还是会显示空或者不完整的数据。

可以在WSAPI Store的load事件里,等所有关联集合加载完成后再调用_getViewStore方法,比如用Ext.Deferred来批量处理:

// 假设me.myFeatureStore是你的WSAPI Store
me.myFeatureStore.on('load', function(store, records) {
    var promises = [];
    _.each(records, function(record) {
        // 等待前置集合加载完成
        var preDeferred = Ext.create('Ext.Deferred');
        record.predecessorStore.load({
            callback: function() {
                preDeferred.resolve();
            }
        });
        promises.push(preDeferred);
        
        // 等待后置集合加载完成
        var sucDeferred = Ext.create('Ext.Deferred');
        record.successorStore.load({
            callback: function() {
                sucDeferred.resolve();
            }
        });
        promises.push(sucDeferred);
    });
    
    // 所有关联集合都加载完后再更新自定义Store和网格
    Ext.Deferred.all(promises).then(function() {
        me._getViewStore();
        me.myGrid.down('rallygrid').reconfigure(me.myViewStore);
    });
});

这样就能保证网格渲染的时候,所有需要的数据都已经准备好,不管是基础字段的格式化,还是前置/后置依赖的展示,都能正常工作。


内容的提问来源于stack exchange,提问作者Michael Østerberg Jakobsen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:02:51