Magento 2-自定义管理网格字段-排序或过滤时出错


9

我将自定义列添加到管理网格,像这样

<column name="customer_name" class="Vendor\Module\Ui\Component\Listing\Columns\CustomerName">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="filter" xsi:type="string">text</item>
                <item name="editor" xsi:type="string">text</item>
                <item name="sortable" xsi:type="string">true</item>
                <item name="label" xsi:type="string" translate="true">Customer Name</item>
                <item name="sortOrder" xsi:type="number">30</item>
            </item>
        </argument>
    </column>

在我的CustomerName类中,我为此列创建值:

public function prepareDataSource(array $dataSource)
{
    $fieldName = $this->getData('name');
    foreach ($dataSource['data']['items'] as & $item) {
        $customer = $this->customerRepository->getById($item['customer_id']);
        $name = $customer ? $customer->getFirstName().' <'.$customer->getEmail().'>' : '';
        $item[$fieldName] = $name;
    }
    return $dataSource;
}

它按预期显示在网格中。但是当我尝试按此列或过滤器排序时-发生错误

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'customer_name' in 'order clause'

我怎样才能解决这个问题?

更新

现在,我尝试通过删除CustomerName类(并在xml的列标记中删除对其的引用)来解决此问题,而是在集合类中添加了_renderFiltersBefore()函数

 protected function _renderFiltersBefore() {
     $joinTable = $this->getTable('customer_entity');
     $this->getSelect()->join($joinTable.' as customer_entity','main_table.customer_id = customer_entity.entity_id', array('*'));
     $this->getSelect()->columns('CONCAT(firstname," <",email,">") as customer_name');
     parent::_renderFiltersBefore();
}

现在排序工作正常,但过滤不起作用(得到相同的错误)

Answers:


13

您可以使用一种工厂方法,这就是addFilterToMap()。Magento 2渲染过滤器仅根据映射的字段替换条件的主题

您可以在_initSelect_renderFiltersBefore方法中调用它。

对于选择中已存在的简单列(可解决歧义错误)

$this
     ->addFilterToMap('customer_id', 'ce.entity_id');

但在您的情况下,需要将表达式映射为

$this
    ->addFilterToMap(
       'customer_name ', 
       new \Zend_Db_Expr('CONCAT(ce.firstname," <",ce.email,">")')
    ); 

因此查询的条件部分将 ... WHERE (CONCAT(ce.firstname," <",ce.email,">") LIKE '%@yippie.com%') ... 改为 ... WHERE (customer_name LIKE '%@yippie.com%') ...

您也可以使用其他与集合相关的工厂方法SELECT在查询的一部分中使用表达式

$this
    ->addExpressionFieldToSelect(
        'firstname',
        new \Zend_Db_Expr('CONCAT(ce.firstname," <",ce.email,">")'),
        []
    )

代替

$this->getSelect()->columns('CONCAT(ce.firstname," <",ce.email,">") as firstname');

非常感谢!挣扎了半天。您在哪里找到/学习的?当然,不是在文档中吗?
雅尼斯·埃默里斯(JānisElmeris)'17

如原始帖子所述:必须将自定义列添加到管理网格-具有过滤器和排序选项。花费大约1.5天的时间解决问题
办公

我正在尝试在我的自定义模块管理网格上同时显示发票和销售订单crement_id,其中销售订单增量ID被重新标记为“ ordincrementid”。甚至我都用过addFilterToMap(); 我无法过滤销售订单增量ID。它返回此错误=> where子句不明确的列'increment_id'
Ask Bytes

6

花了一些时间,但我发现了

在我的xml清单中:

<column name="firstname">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="filter" xsi:type="string">text</item>
                <item name="editor" xsi:type="string">text</item>
                <item name="sortable" xsi:type="string">true</item>
                <item name="label" xsi:type="string" translate="true">Customer Name</item>
                <item name="sortOrder" xsi:type="number">30</item>
            </item>
        </argument>
    </column>

在Vendor \ Module \ Model \ ResourceModel \ SomeCustomModel \ Grid中:

/**
 * adding email to customer name column
 */
protected function _initSelect()
{
    parent::_initSelect();
    $this->getSelect()->joinLeft(
        ['ce' => $this->getTable('customer_entity')],
        'main_table.customer_id = ce.entity_id',
        ['*']
    );

    $this->getSelect()->columns('CONCAT(ce.firstname," <",ce.email,">") as firstname');
    return $this;
}

在Vendor \ Module \ Model \ ResourceModel \ SomeCustomModel中

/**
 * addding ability to filter by column with customer name and email
 */
protected function _renderFiltersBefore()
{
    $wherePart = $this->getSelect()->getPart(\Magento\Framework\DB\Select::WHERE);
    foreach ($wherePart as $key => $cond) {
        $wherePart[$key] = str_replace('`firstname`', 'CONCAT(firstname," <",email,">")', $cond);
    }
    $this->getSelect()->setPart(\Magento\Framework\DB\Select::WHERE, $wherePart);
    parent::_renderFiltersBefore();
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.