批量操作或页面切换后管理网格列发生变化 - Magento 1.9

Admin grid columns change after mass action or page switch - Magento 1.9

问题: AJAX 分页或删除调用后,优惠券网格的新列消失了。

我的目标: 我想通过添加一些列来扩展购物车规则编辑页面中的优惠券网格。

如何: 如果您创建购物车规则并将 "Autogenerate coupons" 复选框设置为 true 并保存,之后您将能够转到“管理优惠券”选项卡并从那里为该规则生成优惠券。

我的 magento 商店使用的优惠券只能使用一次,因此我需要在 特定优惠券时保存记录已经用过。由于 magento 优惠券没有该属性,我使用安装脚本在 salesrule_coupon table 中添加了一列 date_used

<?php
$installer = $this;

$installer->startSetup();

$installer->run("
  ALTER TABLE {$this->getTable('salesrule_coupon')} ADD date_used DATE NULL after created_at;
");

$installer->endSetup();

date_used 已创建,我可以在数据库中看到它。接下来,为了向优惠券网格添加新列,我执行以下操作:

  1. 我在 code/core/Mage/Adminhtml/Block/Promo/Quote/Edit/Tab/Coupons/Grid.php 扩展了网格块 class 并创建了我自己的 code/local/Company/Coupons/Block/Adminhtml/Promo/Quote/Edit/Tab/Coupons/Grid.php

代码如下:

<?php

class Company_Coupons_Block_Adminhtml_Promo_Quote_Edit_Tab_Coupons_Grid extends Mage_Adminhtml_Block_Promo_Quote_Edit_Tab_Coupons_Grid {
    protected function _prepareColumns() {
        parent::_prepareColumns();

        // adding a column with date_used index
        $this->addColumn('date_used', array(
            'header' => Mage::helper('salesrule')->__('Date Used'),
            'index'  => 'date_used',
            'width'  => '50',
            'type'   => 'date',
        ));
        return $this;
    }
}
  1. 创建布局文件 coupons.xml 并将其放入设计中 design/adminhtml/company/default/layout/coupons.xml。在此布局中,我将自己的优惠券网格块添加为 company_coupons/adminhtml_promo_quote_edit_tab_coupons_grid 并删除了 magento 的 promo_quote_edit_tab_coupons_grid。如您所见,一切都发生在 adminhtml_promo_quote_edit 块内。

布局文件:

<!-- adding own grid block and removing magento core grid from this block-->
<layout>
    <adminhtml_promo_quote_edit>
        <reference name="promo_quote_edit_tab_coupons">
            <block type="company_coupons/adminhtml_promo_quote_edit_tab_coupons_grid" name="coupongrid" after="promo_quote_edit_tab_coupons_grid"/>
            <remove name="promo_quote_edit_tab_coupons_grid"/>
        </reference>
    </adminhtml_promo_quote_edit>
</layout>
  1. 最后,我在 etc/config.xml 文件中注册了这些更改。

配置文件:

<?xml version="1.0"?>
<config>
    <modules>
        <Company_Coupons>
            <version>0.1.2</version>
        </Company_Coupons>
    </modules>
    <global>
        <helpers>
            <company_coupons>
                <class>Company_Coupons_Helper</class>
            </company_coupons>
        </helpers>
        <blocks>
            <company_coupons>
                <class>Company_Coupons_Block</class>
            </company_coupons>
        </blocks>
        <models>
            <company_coupons>
                <class>Company_Coupons_Model</class>
            </company_coupons>
        </models>
        <resources>
            <coupons_setup>
                <setup>
                    <module>Company_Coupons</module>
                </setup>
                <connection>
                    <use>core_setup</use>
                </connection>
            </coupons_setup>
            <coupons_write>
                <connection>
                    <use>core_write</use>
                </connection>
            </coupons_write>
            <coupons_read>
                <connection>
                    <use>core_read</use>
                </connection>
            </coupons_read>
        </resources>
        <events>
            <sales_order_place_after>
                <observers>
                    <coupons>
                        <class>company_coupons/observer</class>
                        <method>saveCouponUsageInfo</method>
                    </coupons>
                </observers>
            </sales_order_place_after>
        </events>
    </global>
    <adminhtml>
        <layout>
            <updates>
                <coupons>
                    <file>coupons.xml</file>
                </coupons>
            </updates>
        </layout>
    </adminhtml>
</config> 
  1. 我还在 Model/Observer.php 中添加了 saveCouponUsageInfo(Varien_Event_Observer $observer) 方法,但我不会包括它,因为它工作得很好。

我的解决方案有效,我可以清楚地看到我的网格中的新列:

但是! 如果我执行 ajax 操作,例如请求网格的第二页或批量删除,我的列就会消失并且网格包含其旧的一组列。当然,如果我重新加载整个页面,date_used 列会返回到网格。见下文 (图像被裁剪,第 2 页有 20 张优惠券):


我在 PhpStorm 中使用调试器并注意到优惠券网格 html,在批量删除后,请求者:

/index.php/admin/promo_quote/couponsGrid/id/64/key/1eccc1c40033fa8bf64007738a22dc1a?ajax=true&isAjax=true

用于分页的相同请求,但将页码添加到 URL:

/index.php/admin/promo_quote/couponsGrid/id/64/key/1eccc1c40033fa8bf64007738a22dc1a/page/2/?ajax=true&isAjax=true

您可能已经从 URL 中猜到,在这些调用期间 Mage_Adminhtml_Promo_QuoteController 中的 couponsGridAction() 方法被触发。问题是我的 _prepareColumns() 实现从未被调用,正如调试器所揭示的那样。因此 date_used 列不再包含。

以前有人遇到过这个问题吗?我在这个小错误上花了一整天,如果有任何提示或指导,我将不胜感激。谢谢。

如果您查看执行的控制器操作,即 Mage_Adminhtml_Promo_QuoteController::couponsGridAction(),您会看到它执行通常的操作 $this->loadLayout()->renderLayout();,这意味着为此 AJAX 定义了一个布局动作。
打开 app/design/adminhtml/default/default/layout/promo.xml,您将在底部看到为该特定操作定义的布局:

    <adminhtml_promo_quote_couponsgrid>
        <block type="core/text_list" name="root" output="toHtml">
            <block type="adminhtml/promo_quote_edit_tab_coupons_grid" name="promo_quote_edit_tab_coupons_grid" />
        </block>
    </adminhtml_promo_quote_couponsgrid>

因此您需要在布局 coupons.xml 文件中为该操作定义句柄,如下所示:

    <adminhtml_promo_quote_couponsgrid>
        <block type="core/text_list" name="root" output="toHtml">
            <block type="company_coupons/adminhtml_promo_quote_edit_tab_coupons_grid" name="promo_quote_edit_tab_coupons_grid" />
        </block>
    </adminhtml_promo_quote_couponsgrid>

如您所见,我只是在块的类型声明中将 adminhtml 更改为 company_coupons,并更新了模块 class 的路径,它确实有效(如您的问题有很好的记录我实际上可以在本地重现它并且这个代码已经过实际测试),就这么简单:)