私は、Shopware プラグインを拡張して変更するタスクを割り当てられました。原作者はもう会社にいません。それ以前は、Shopware と ExtJ を扱ったことはありません。だから私はここ数日、自分自身をそれに慣れさせるのに費やしており、これまでのところ原則とパラダイムを理解したと思います.
私が現在問題を抱えている唯一のことは、次の問題です。
Ext.tree.Panel
Ajax を使用してデータベースに保存したいものがあります。ノードがツリーに追加され、GUI に表示されます。しかし、呼び出した後optionsTree.getStore().sync()
、データベースには何も到着しません。PHPコントローラーのcreateProductOptionAction()
は呼び出されませんが、理由がわかりません。ブラウザ コンソール ログにエラー メッセージはなく、Shopware ログ ファイルにもエラー メッセージはありません。何もない。すべてがうまくいくようです。しかし、データは保存されていません。
元のプラグインには、Ext.grid.Panel
データを保存および表示するための がありました。そして、これはうまくいきます。しかしExt.tree.Panel
、コードを変更して修正すると、もう機能しません。私の観点からは、それはうまくいくはずです。しかし、そうではなく、自分の間違いを見ることができません。
私はまだ ExtJ の血まみれの初心者です。:)
これが私がこれまでに得たものです:
app.js
Ext.define('Shopware.apps.CCBConfigurablePhotoProductsManager', {
extend:'Enlight.app.SubApplication',
name:'Shopware.apps.CCBConfigurablePhotoProductsManager',
bulkLoad: true,
loadPath:'{url controller="CCBConfigurablePhotoProductsManager" action="load"}',
controllers:['ProductConfigurator'],
stores:['ProductOptionsList'],
models:['ProductOption'],
views: ['ProductOptions', 'Window' ],
launch: function() {
var me = this,
mainController = me.getController('ProductConfigurator');
return mainController.mainWindow;
}
});
コントローラー/controller.js
Ext.define('Shopware.apps.CCBConfigurablePhotoProductsManager.controller.ProductConfigurator', {
extend:'Ext.app.Controller',
refs: [
{ ref: 'productOptionsTree', selector: 'product-configurator-settings-window product-options-tree' }
],
init:function () {
var me = this;
me.mainWindow = me.createMainWindow();
me.addControls();
me.callParent(arguments);
return me.mainWindow;
},
addControls: function() {
var me = this;
me.control({
'product-configurator-settings-window product-options-tree': {
addProductOption: me.onAddProductOption
}
});
},
createMainWindow: function() {
var me = this,
window = me.getView('Window').create({
treeStore: Ext.create('Shopware.apps.CCBConfigurablePhotoProductsManager.store.ProductOptionsList').load()
}).show();
return window;
},
onAddProductOption: function() {
var me = this,
optionsTree = me.getProductOptionsTree(),
parentNode = optionsTree.getRootNode(),
nodeCount = parentNode.childNodes.length + 1,
productOption = Ext.create('Shopware.apps.CCBConfigurablePhotoProductsManager.model.ProductOption', {
parent: 0,
type: 0,
title: Ext.String.format('{s name="group/default_name"}New Group [0]{/s}', optionsTree.getRootNode().childNodes.length + 1),
active: true,
leaf: false
});
productOption.setDirty();
parentNode.appendChild(productOption);
optionsTree.getStore().sync(); // Nothing arrives at DB
optionsTree.expandAll();
},
// ...
ビュー/window.js
Ext.define('Shopware.apps.CCBConfigurablePhotoProductsManager.view.Window', {
extend:'Enlight.app.Window',
cls:Ext.baseCSSPrefix + 'product-configurator-settings-window',
alias:'widget.product-configurator-settings-window',
border:false,
autoShow:true,
maximizable:true,
minimizable:true,
layout: {
type: 'hbox',
align: 'stretch'
},
width: 700,
height: 400,
initComponent:function () {
var me = this;
me.createItems();
me.title = '{s name=window/title}Configurator Settings{/s}';
me.callParent(arguments);
},
createItems: function() {
var me = this;
me.items = [
me.createProductOptionsTree()
];
},
createProductOptionsTree: function() {
var me = this;
return Ext.create('Shopware.apps.CCBConfigurablePhotoProductsManager.view.ProductOptions', {
store: me.treeStore,
width: '20%',
flex: 1
});
}
});
store/product_options_list.js
Ext.define('Shopware.apps.CCBConfigurablePhotoProductsManager.store.ProductOptionsList', {
extend: 'Ext.data.TreeStore',
pageSize: 30,
autoLoad: false,
remoteSort: true,
remoteFilter: true,
model : 'Shopware.apps.CCBConfigurablePhotoProductsManager.model.ProductOption',
proxy:{
type:'ajax',
url:'{url controller="CCBConfigurablePhotoProductsManager" action="getProductOptionsList"}',
reader:{
type:'json',
root:'data',
totalProperty:'total'
}
}
});
model/product_option.js
Ext.define('Shopware.apps.CCBConfigurablePhotoProductsManager.model.ProductOption', {
extend : 'Ext.data.Model',
fields : [
{ name : 'id', type : 'int', useNull: true },
{ name : 'parent', type : 'int' },
{ name : 'title', type : 'string' },
{ name : 'active', type: 'boolean' },
{ name : 'type', type : 'int' }
],
idProperty : 'id',
proxy : {
type : 'ajax',
api: {
create: '{url controller="CCBConfigurablePhotoProductsManager" action="createProductOption"}',
update: '{url controller="CCBConfigurablePhotoProductsManager" action="updateProductOption"}',
destroy: '{url controller="CCBConfigurablePhotoProductsManager" action="deleteProductOption"}'
},
reader : {
type : 'json',
root : 'data',
totalProperty: 'total'
}
}
});
php/controller.php
<?php
use Shopware\CustomModels\CCB\ProductOption;
class Shopware_Controllers_Backend_CCBConfigurablePhotoProductsManager extends Shopware_Controllers_Backend_ExtJs
{
public function createProductOptionAction()
{
// Never being called
file_put_contents('~/test.log', "createProductOptionAction\n", FILE_APPEND);
$this->View()->assign(
$this->saveProductOption($this->Request()->getParams())
);
}
public function getProductOptionsListAction()
{
// Works fine
file_put_contents('~/test.log', "getProductOptionsListAction\n", FILE_APPEND);
// ...
}
// ...
編集1
サキさんの提案通り、ショップとモデルの両方にライターを追加してみました。しかし、残念ながらまだうまくいきません。createProductOptionAction()
PHP コントローラーの が呼び出されることはありません。
Ext.define('Shopware.apps.CCBConfigurablePhotoProductsManager.model.ProductOption', {
extend : 'Ext.data.Model',
fields : [
{ name : 'id', type : 'int', useNull: true },
{ name : 'parent', type : 'int' },
{ name : 'title', type : 'string' },
{ name : 'active', type: 'boolean' },
{ name : 'type', type : 'int' }
],
idProperty : 'id',
proxy : {
type: 'ajax',
api: {
create: '{url controller="CCBConfigurablePhotoProductsManager" action="createProductOption"}',
update: '{url controller="CCBConfigurablePhotoProductsManager" action="updateProductOption"}',
destroy: '{url controller="CCBConfigurablePhotoProductsManager" action="deleteProductOption"}'
},
reader: {
type : 'json',
root : 'data',
totalProperty: 'total'
},
writer: {
type: 'json'
}
}
});
私が不思議に思っているのは、元のプラグインにはライターが実装されていなかったということです。しかし、エントリを追加すると、すぐにデータベースに表示されました。
編集2
にいくつかのリスナーを追加しましたstore.ProductOptionsList
:
Ext.define('Shopware.apps.CCBConfigurablePhotoProductsManager.store.ProductOptionsList', {
extend: 'Ext.data.TreeStore',
pageSize: 30,
autoLoad: false,
remoteSort: true,
remoteFilter: true,
model : 'Shopware.apps.CCBConfigurablePhotoProductsManager.model.ProductOption',
root: {
text: 'Product Options',
id: 'productOptions',
expanded: true
},
proxy:{
type: 'ajax',
url: '{url controller="CCBConfigurablePhotoProductsManager" action="getProductOptionsList"}',
reader: {
type:'json',
root:'data',
totalProperty:'total'
}
},
listeners: {
add: function(store, records, index, eOpts) {
console.log("**** Add fired");
console.log(records);
},
append: function(store, node, index, eOpts) {
console.log("**** Append fired");
console.log(node);
},
beforesync: function(operations) {
console.log("**** Beforesync fired");
console.log(operations);
}
}
});
これらのイベントはすべて発生しています。beforesync
イベントショー
**** Beforesync fired
Object {create: Array[1]}
create: Array[1]
...
それでも、 の API リクエストはmodel.ProductOption
起動されません。それはうまくいくはずです。そうじゃない?これは ExtJS 4.1 のバグでしょうか? または、Shopware + ExtJS で何か?
編集3
わかりました、これは本当に奇妙になっています。
に「書き込み」リスナーを追加しましたTreeStore
。
write: function(store, operation, opts){
console.log("**** Write fired");
console.log(operation);
Ext.each(operation.records, function(record){
console.log("**** ...");
if (record.dirty) {
console.log("**** Commiting dirty record");
record.commit();
}
});
}
ノードを追加して を呼び出した.getStore().sync()
後、write
イベントが発生し、彼は を繰り返しoperation.records
、1 つのレコード (追加したばかりのレコード) を見つけます... しかし、ツリーに追加する前に行ったdirty
にもかかわらず、そうではありませんか?!productOption.setDirty()
お時間をありがとうございました!:)