Ответ 1
Я нашел проблему, или, скорее, путаница лежит в методе getRecords()
Ext.data.Operation
. Этот метод возвращает "операция, первоначально настроенная запись будет возвращена, хотя прокси-сервер может изменить данные этих записей в какой-то момент после инициализации операции". согласно документации.
Это довольно запутанная ИМО, поскольку возвращаемая запись действительно обновляется, однако созданный магазин ассоциаций и, следовательно, связанные данные не являются! Это то, что привело к моей путанице, показалось, что запись содержала обновленные данные с сервера приложений, но это было не так.
Чтобы облегчить мой простой ум при получении обновленных данных FULLY из ответа, я добавил метод в класс Ext.data.Operation
... Я просто написал этот метод и не получил испытал его больше, чем обеспечение функциональности, которую я искал, поэтому используйте на свой страх и риск!
Пожалуйста, имейте в виду, что я не вызываю store.sync(), скорее я создаю экземпляр модели и вызываю метод model.save(), поэтому мой результирующий набор обычно содержит только одну запись...
Ext.override(Ext.data.Operation,{
getSavedRecord: function(){
var me = this, // operation
resultSet = me.getResultSet();
if(resultSet.records){
return resultSet.records[0];
}else{
throw "[Ext.data.Operation] EXCEPTION: resultSet contains no records!";
}
}
});
Теперь я могу достичь функциональности, которой я был после...
// Get the unsaved data
store = Ext.create('App.store.test.Simpson');
homer = store.getById(1);
unsavedChildren = '';
Ext.each(homer.getKids().getRange(), function(kid){
unsavedChildren += kid.get('name') + ",";
});
console.log(unsavedChildren); // Bart Simpson, Lisa Simpson, Maggie Simpson
// Invokes the UPDATE Method on the proxy
// See original post for server response
home.save({
success: function(rec, op){
var savedRecord = op.getSavedRecord(), // the magic! /sarcasm
savedKids = '';
Ext.each(savedRecord.getKids().getRange(), function(kid){
savedKids += kid.get('name') + ',';
});
console.log("Saved Children", savedKids);
/** Output is now Correct!!
SAVED Bart Simpson, SAVED Lisa Simpson, SAVED Maggie Simpson
*/
}
});
Редактировать 12/10/13
Я также добавил метод Ext.data.Model
, который я назвал updateTo
, который обрабатывает обновление записи к предоставленной записи, которая также обрабатывает ассоциации. Я использую это в сочетании с вышеупомянутым методом getSavedRecord
. Обратите внимание, что это не обрабатывает ассоциации belongsTo
, поскольку я не использую их в своем приложении, но эту функциональность можно будет легко добавить.
/**
* Provides a means to update to the provided model, including any associated data
* @param {Ext.data.Model} model The model instance to update to. Must have the same modelName as the current model
* @return {Ext.data.Model} The updated model
*/
updateTo: function(model){
var me = this,
that = model,
associations = me.associations.getRange();
if(me.modelName !== that.modelName)
throw TypeError("updateTo requires a model of the same type as the current instance ("+ me.modelName +"). " + that.modelName + " provided.");
// First just update the model fields and values
me.set(that.getData());
// Now update associations
Ext.each(associations, function(assoc){
switch(assoc.type){
/**
* hasOne associations exist on the current model (me) as an instance of the associated model.
* This instance, and therefore the association, can be updated by retrieving the instance and
* invoking the "set" method, feeding it the updated data from the provided model.
*/
case "hasOne":
var instanceName = assoc.instanceName,
currentInstance = me[instanceName],
updatedInstance = that[instanceName];
// Update the current model hasOne instance with data from the provided model
currentInstance.set(updatedInstance.getData());
break;
/**
* hasMany associations operate from a store, so we need to retrieve the updated association
* data from the provided model (that) and feed it into the current model (me) assocStore
*/
case "hasMany":
var assocStore = me[assoc.storeName],
getter = assoc.name,
newData = that[getter]().getRange();
// Update the current model hasMany association store with data from the provided model hasMany store
assocStore.loadData(newData);
break;
// If for some reason a bogus association type comes through, throw a type error
// At this time I have no belongsTo associations in my application, so this TypeError
// may one day appear if I decide to implement them.
default:
throw TypeError("updateTo does not know how to handle association type: " + assoc.type);
break;
}
});
// Commit these changes
me.commit();
return me;
}
Итак, в основном я делаю что-то вроде этого (это теоретически было бы в контроллере Order)
doSaveOrder: function(order){
var me = this, // order controller
orderStore = me.getOrderStore(); // magic method
// Save request
order.save({
scope: me,
success: function(responseRecord, operation){
// note: responseRecord does not have updated associations, as per post
var serverRecord = operation.getSavedRecord(),
storeRecord = orderStore.getById(order.getId());
switch(operation.action){
case 'create':
// Add the new record to the client store
orderStore.add(serverRecord);
break;
case 'update':
// Update existing record, AND associations, included in server response
storeRecord.updateTo(serverRecord);
break;
}
}
});
}
Я надеюсь, что это поможет кому-то, кто был смущен, как и я!