Magento的后台有两种最主要的通用组件:Grid和Form,基本上所有看到的列表表格都是Grid(继承自Mage_Adminhtml_Block_Widget_Grid),基本上所有看到的表单都是Form(继承自Mage_Adminhtml_Block_Widget_Form)。Magento的Grid是个非常好用的组件,用户只需要按照它的结构写法,指定数据源和需要显示的字段,组件会自动提供包括分页,排序,过滤,导出和批量处理等功能。
为什么说Magento的Grid的bug呢,问题就出在过滤这里。作为一个开源的系统,Magento需要考虑最大的通用性,所以在Grid组件的设计上,所有的文本框类型(Text)的字段列,过滤的时候都是模糊查询(like %XXX%),数据量小的时候,这都不是事,数据量大到一定程度,速度慢不说,每一次的过滤操作都是对数据库的一次摧残(效果详见Mysql的慢查询日志)。
打开Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Abstract,可以看到如下代码:
public function getCondition()
{
$helper = Mage::getResourceHelper('core');
$likeExpression = $helper->addLikeEscape($this->getValue(), array('position' => 'any'));
return array('like' => $likeExpression);
}
所有类型的Grid字段(Text,Select,Price...)都继承了Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Abstract,其中Select类型重写了getCondition方法,使用了精确查询(‘eq’),而Text类型没有重写getCondition方法,结果就是上文讲的,一切过滤都是模糊查询(like %XXX%)。
解决这个问题的方式有两类,第一类方式是在输入过滤词的时候额外加符号(比如*,%)来标识是否使用模糊查询(当然前提是底层组件代码做修改来处理这种情况),处理方式参见 New way to search through Magento administration grids – using *s 。第二类方式是通过特定的标记,一个个指定哪些字段是可以使用精确查询的,哪些需要保留模糊查询。第一种的优点是保持了高灵活性,可以通过自己输入符号来控制是否精确查询,并且代码修改量很少,缺点是要求操作后台的人员都要改变以往的操作习惯,记住符号的使用规则,第二种方式的缺点是需要针对每个Grid的字段做评估(精确还是模糊),然后一个个Grid做出相应的修改,代码修改量比较大,优点是操作人员不需要改变以往的操作习惯,没有任何学习成本。
从实际情况来讲,第一种方式是不可取的,是典型的程序员思维,而没有站在普通操作人员(完全不懂程序的概念)的角度考虑问题,操作人员不关心你程序背后的逻辑是什么样,也不会配合你在做过滤操作时输入各种不懂的符号。所以好模板采用的是第二种方式,修改了Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Text文件,重写了父类中的getCondition方法,对标记为需要模糊查询的字段进行模糊查询(like),未标记的采用精确查询,虽然前期准备工作很多,但整个修改对于一线操作人员几乎是黑盒的,修改前后的操作可以无缝的延续。
(责任编辑:好模板) |