问题
In the code below, in _copyChild and innerModelRetrieved functions print on console 4 features one by one, but in next function onInnerModelRetrieved 4 times last feature value is printed, I am not able to figure it why its happening like that. please help me with this.
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
_newObj : {},
childrens: [],
_type : null,
launch: function() {
Ext.create('Rally.ui.dialog.ChooserDialog', {
width: 450,
autoScroll: true,
height: 525,
title: 'Select to Copy',
pageSize: 100,
closable: false,
selectionButtonText: 'Copy',
artifactTypes: ['PortfolioItem/Feature','PortfolioItem/MMF','PortfolioItem/Epic', 'PortfolioItem/Program'],
autoShow: true,
storeConfig:{
fetch: ['Name','PortfolioItemTypeName']
},
listeners: {
artifactChosen: function(selectedRecord) {
childrens = [];
this._type = selectedRecord.get('PortfolioItemTypeName');
this._newObj = selectedRecord;
this.onqModelRetrieved();
var self = this;
Ext.create('Rally.data.wsapi.Store', {
model: 'PortfolioItem/' + selectedRecord.get('PortfolioItemTypeName'),
fetch: ['Name', 'FormattedID', 'Children'],
pageSize: 1,
autoLoad: true,
listeners: {
load: function(store, records) {
final_features = [];
Ext.Array.each(records, function(child){
var item = selectedRecord;
childrens = item.getCollection('Children');
childrens.load({
fetch: ['FormattedID'],
callback: function(records, operation, success){
Ext.Array.each(records, function(portfolioitem){
if (portfolioitem.get('PortfolioItemTypeName') == "Feature") {
self._childObj = portfolioitem;
self._copyChild();
}
}, self);
},
scope: this
});
}, self);
}
}
});
},
scope: this
},
});
},
// Inner Copy functions
_copyChild: function() {
console.log("child value here", that._childObj);
this.innerModelRetrieved();
},
innerModelRetrieved: function() {
var that = this
console.log("next child value here", that._childObj);
that._type = 'PortfolioItem/' + that._childObj.get('PortfolioItemTypeName');
Rally.data.ModelFactory.getModel({
type: that._type,
success: that.onInnerModelRetrieved,
scope: that
});
},
onInnerModelRetrieved: function(model) {
console.log("next child value here", this._childObj);
this.model = model;
this.genericInnerCopy(model);
},
回答1:
In order to make this work you need to create a block scope and a local variable that is set to the current childObj, otherwise onInnerModelRetrieved gets only the last value of childObj since it waits for the iterations over results to complete before it kicks in.
The function
(function(){...})();
immediately invoked creates that block scope and
var child = that._childObj
captures individual objects at each iteration.
Finally, the child is passed via
success: function(model)
which invokes onInnerModelRetrieved with two parameters, model and child
innerModelRetrieved: function() {
var that = this;
(function(){
var child = that._childObj;
console.log("in innerModelRetrieved, that._childObj.data.FormattedID:", that._childObj.data.FormattedID);
that._type = 'PortfolioItem/' + that._childObj.get('PortfolioItemTypeName');
Rally.data.ModelFactory.getModel({
type: that._type,
success: function(model){
that.onInnerModelRetrieved(model, child );
},
scope: that
});
})();
},
onInnerModelRetrieved: function(model, _childObj ) {
console.log("in onInnerModelRetrieved, that._childObj.data.FormattedID:", _childObj.data.FormattedID);
this.model = model;
}
Here is the screenshot before the changes:
And here is the screenshot after changes:
来源:https://stackoverflow.com/questions/25967655/last-record-value-is-displayed-not-all-values-are-looped