0

私は、Shopware プラグインを拡張して変更するタスクを割り当てられました。原作者はもう会社にいません。それ以前は、Shopware と ExtJ を扱ったことはありません。だから私はここ数日、自分自身をそれに慣れさせるのに費やしており、これまでのところ原則とパラダイムを理解したと思います.

私が現在問題を抱えている唯一のことは、次の問題です。

Ext.tree.PanelAjax を使用してデータベースに保存したいものがあります。ノードがツリーに追加され、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()

お時間をありがとうございました!:)

4

2 に答える 2

0

ストアで使用されるプロキシには、サーバーと通信するための同期操作用に構成されたライターが必要です。

于 2015-02-05T12:42:47.627 に答える