Ich habe ein ExtJS Backendmodul mit einer Liste von Items. Jedes Item hat eine Detail-View mit mehreren Associationen. Manche Associationen sind OneToMany, welche ebenfalls ein Detail-Window hat. Wenn ich nun das Detail-Window eines dieser Associationen öffne, dort Werte Ändere und speicher (Associationen-Detail schließe), sehe ich die Änderungen in meiner Item-Detail Associationen Liste und zusätzlich sind die geänderten Werte mit einem roten Dreieck markiert. Soweit so gut. Wenn ich nun das Item in der Detail speichere, werden aber nicht die geänderten Associationen-Daten übermittelt (nachgeschaut im XHR update), sondern noch die alten, obwohl die List-View die geänderten Werte anzeigt. Ergo werden die Änderungen auch nicht gespeichert. Was mache ich falsch?
Hier auszüge des Quellcodes:
Item List Window
Ext.define('Shopware.apps.LNItem.view.lnitem.list.Window', {
extend: 'Shopware.window.Listing',
alias: 'widget.lnitem-view-lnitem-list-window',
width: '100%',
height: '100%',
configure: function() {
return {
listingGrid: 'Shopware.apps.LNItem.view.lnitem.list.LNItem',
listingStore: 'Shopware.apps.LNItem.store.LNItem'
};
}
});
Item List List
Ext.define('Shopware.apps.LNItem.view.lnitem.list.LNItem', {
extend: 'Shopware.grid.Panel',
alias: 'widget.lnitem-view-lnitem-list-lnitem',
region: 'center',
configure: function () {
return {
columns: {
id: { },
sku: { },
blocked: { },
onClearance: { },
onSale: { },
visibility: { },
cost: { },
baseUnit: { },
salesUnit: { },
atInventory: { },
atSalesOrder: { },
atPurchaseOrder: { },
reorderDurationDays: { },
originCountry: { },
tariff: { },
datetimeCreated: { },
datetimeCreatedUtc: { },
datetimeModified: { }
},
*/
toolbar: true,
// displays the add button (true|false)
addButton: false,
// displays the search field (true|false)
searchField: true,
// displays the action column (true|false)
actionColumn: true,
// displays the delete column (true|false)
deleteColumn: false,
// more see at source of Shopware.grid.Panel in base/application/Shopware.grid.Panel.js
detailWindow: 'Shopware.apps.LNItem.view.lnitem.detail.Window'
};
}
});
Item Detail Window
Ext.define('Shopware.apps.LNItem.view.lnitem.detail.Window', {
extend: 'Shopware.window.Detail',
alias: 'widget.lnitem-view-lnitem-detail-window',
title: '',
height: 420,
width: 900
});
Item Detail Container
Ext.define('Shopware.apps.LNItem.view.lnitem.detail.LNItem', {
extend: 'Shopware.model.Container',
alias: 'widget.lnitem-view-lnitem-detail-lnitem',
padding: 20,
configure: function() {
return {
controller: 'LNItem',
associations: [
'texts'
]
};
}
});
Texts Assoc List
Ext.define('Shopware.apps.LNItem.model.LNItemTranslation', {
extend: 'Shopware.data.Model',
configure: function() {
return {
listing: 'Shopware.apps.LNItem.view.lnitem.detail.LNItemTextsList',
detail: 'Shopware.apps.LNItem.view.lnitemtranslation.detail.LNItemTranslation'
};
},
fields: [
{ name: 'productId', type: 'string', useNull: true },
{ name: 'languageCode', type: 'string', useNull: true },
{ name: 'name', type: 'string' },
{ name: 'description', type: 'string' },
{ name: 'keywords', type: 'string' },
{ name: 'bulletpoint1', type: 'string' },
{ name: 'bulletpoint2', type: 'string' },
{ name: 'bulletpoint3', type: 'string' },
{ name: 'bulletpoint4', type: 'string' },
{ name: 'bulletpoint5', type: 'string' }
]
});
Texts Detail Window
Ext.define('Shopware.apps.LNItem.view.lnitemtranslation.detail.Window', {
extend: 'Shopware.window.Detail',
alias: 'widget.lnitem-view-lnitemtranslation-detail-window',
title: '',
height: 420,
width: 900,
configure: function() {
return {
eventAlias: 'lnitemtranslation-detail'
};
}
});
Texts Detail Container
Ext.define('Shopware.apps.LNItem.view.lnitemtranslation.detail.LNItemTranslation', {
extend: 'Shopware.model.Container',
alias: 'widget.lnitem-view-lnitemtranslation-detail-lnitemtranslation',
padding: 20
});
Jetzt die noch die Models:
Item Model
Ext.define('Shopware.apps.LNItem.model.LNItem', {
extend: 'Shopware.data.Model',
configure: function() {
return {
controller: 'LNItem',
detail: 'Shopware.apps.LNItem.view.lnitem.detail.LNItem'
};
},
fields: [
{ name: 'id', type: 'string', useNull: true },
{ name: 'sku', type: 'string' },
{ name: 'blocked', type: 'boolean' },
{ name: 'onClearance', type: 'boolean' },
{ name: 'onSale', type: 'boolean' },
{ name: 'visibility', type: 'string' },
{ name: 'cost', type: 'float' },
{ name: 'baseUnit', type: 'string' },
{ name: 'salesUnit', type: 'string' },
{ name: 'atInventory', type: 'float' },
{ name: 'atSalesOrder', type: 'float' },
{ name: 'atPurchaseOrder', type: 'float' },
{ name: 'reorderDurationDays', type: 'int' },
{ name: 'originCountry', type: 'string' },
{ name: 'tariff', type: 'string' },
{ name: 'datetimeCreated', type: 'date', dateFormat: 'Y-m-d H:i:s' },
{ name: 'datetimeCreatedUtc', type: 'date', dateFormat: 'Y-m-d H:i:s' },
{ name: 'datetimeModified', type: 'date', dateFormat: 'Y-m-d H:i:s' },
{ name: 'datetimeModifiedUtc', type: 'date', dateFormat: 'Y-m-d H:i:s' },
{ name: 'datetimeProductReleased', type: 'date', dateFormat: 'Y-m-d H:i:s' },
{ name: 'datetimeProductReleasedUtc', type: 'date', dateFormat: 'Y-m-d H:i:s' }
],
associations: [
{ relation: 'OneToMany', type: 'hasMany', model: 'Shopware.apps.LNItem.model.LNItemTranslation', name: 'getTexts', associationKey: 'texts' }
]
});
Und das Text Model
Ext.define('Shopware.apps.LNItem.model.LNItemTranslation', {
extend: 'Shopware.data.Model',
configure: function() {
return {
listing: 'Shopware.apps.LNItem.view.lnitem.detail.LNItemTextsList',
detail: 'Shopware.apps.LNItem.view.lnitemtranslation.detail.LNItemTranslation'
};
},
fields: [
{ name: 'itemId', type: 'string', useNull: true },
{ name: 'languageCode', type: 'string', useNull: true },
{ name: 'name', type: 'string' },
{ name: 'description', type: 'string' },
{ name: 'keywords', type: 'string' },
{ name: 'bulletpoint1', type: 'string' },
{ name: 'bulletpoint2', type: 'string' },
{ name: 'bulletpoint3', type: 'string' },
{ name: 'bulletpoint4', type: 'string' },
{ name: 'bulletpoint5', type: 'string' }
]
});
Dabei ist zu erwähnen, dass im Doctrine-Model die Ids für das Translation ein zusammengesetzter Schlüssel aus ItemId und LanguageCode ist.