正如 Trever 所说,在 Lookback API 中,用户字段不能被水合。
至于使用 wsapi 水合用户字段的示例,下面的代码使用shapshotstore获取快照 where '_PreviousValues.Blocked' : {$exists: true}
,然后使用Rally.data.ModelFactory获取每个快照中所有者的 DisplayName。
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
scopeType: 'iteration',
comboboxConfig: {
labelWidth: 100,
width: 300
},
launch: function() {
var that = this;
var iterationComboBox = Ext.create('Rally.ui.combobox.IterationComboBox',{
listeners:{
ready: function(combobox){
var iterationOid = combobox.getRecord().get('ObjectID');
that._loadStories(iterationOid);
},
select: function(combobox){
var iterationOid = combobox.getRecord().get('ObjectID');
this._loadStories(iterationOid);
},
scope: this
}
});
this.add(iterationComboBox);
},
_loadStories:function(iterationOid){
var that = this;
var snapshotStore = Ext.create('Rally.data.lookback.SnapshotStore', {
autoLoad:true,
find: {
'_TypeHierarchy': 'HierarchicalRequirement',
'_ProjectHierarchy': 12352608219,
'_PreviousValues.Blocked' : {$exists: true},
'Iteration': iterationOid
},
fetch: ['Name','FormattedID','ScheduleState','Blocked','_ValidFrom','_ValidTo', 'BlockedReason','Owner'],
order: 'OpenedDate DESC',
hydrate: ['Blocked','ScheduleState'],
compress: true,
listeners: {
load: function(store,records,success){
console.log("loaded %i records", records.length);
that._onStoriesLoaded(snapshotStore, records);
},
scope:this
}
});
},
_onStoriesLoaded:function(store, records){
var that = this;
var promises = [];
_.each(records, function(story) {
promises.push(that._hydrateOwner(story, that));
});
Deft.Promise.all(promises).then({
success: function(results) {
that._stories = results;
console.log('that._stories', that._stories);
that._makeGrid();
}
});
},
_hydrateOwner:function(story, scope){
var deferred = Ext.create('Deft.Deferred');
var that = scope;
var ownerDisplayName = null;
var userOid = story.get('Owner');
var storyBlocked = story.get('Blocked');
Rally.data.ModelFactory.getModel({
type: 'User',
scope: this,
success: function(model, operation) {
fetch: ['UserName', 'DisplayName'],
model.load(userOid, {
scope: this,
success: function(record, operation) {
owner = record.get('DisplayName');
var fid = story.get('FormattedID');
var state = story.get('ScheduleState');
var name = story.get('Name');
var blocked = story.get('Blocked');
result = {
"fid" : fid,
"name" : name,
"state" : state,
"blocked" : blocked,
"owner" : owner
};
deferred.resolve(result);
}
});
}
});
return deferred;
},
_makeGrid: function() {
if (this.down('#grid')) {
this.down('#grid').destroy();
}
var gridStore = Ext.create('Rally.data.custom.Store', {
data: this._stories
});
var _grid = Ext.create('Rally.ui.grid.Grid', {
itemId: 'grid',
store: gridStore,
columnCfgs: [
{
text: 'Name', dataIndex: 'name'
},
{
text: 'FormattedID', dataIndex: 'fid'
},
{
text: 'ScheduleState', dataIndex: 'state'
},
{
text: 'Blocked', dataIndex: 'blocked'
},
{
text: 'Owner', dataIndex: 'owner'
}
]
});
this.add(_grid);
this._grid.reconfigure(gridStore);
}
});