Magento2: store_id в компоненте листинга пользовательского интерфейса


8

Я разрабатываю расширение Magento2, которое имеет сетку администратора, которая генерируется с использованием компонента LI Listing. Сетка показывает записи (список элементов блога) просто отлично. Расширение позволяет сохранять элементы блога для определенных просмотров магазина, который сохраняет blog_id вместе с store_id в отдельной таблице базы данных. Теперь я хотел бы показать столбец в сетке с элементами блога, который показывает представления магазина, выбранные для каждого элемента блога.

Вся установка очень похожа на страницы CMS и cms_page_listing.xml. В моем blog_listing.xml есть столбец для представления магазина следующим образом:

<column name="store_id" class="Magento\Store\Ui\Component\Listing\Column\Store">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>
            <item name="sortable" xsi:type="boolean">false</item>
            <item name="label" xsi:type="string" translate="true">Store View</item>
        </item>
    </argument>
</column>

При загрузке сетки отображается следующая ошибка: « Примечание: неопределенный индекс: store_id в .. \ vendor \ magento \ module-store \ Ui \ Component \ Listing \ Column \ Store.php в строке 82 »

Очевидно, что в коллекции элементов блога по умолчанию нет store_id, поскольку он связан через другую таблицу с фактическими идентификаторами store_id. Но моя коллекция выглядит так, и она должна быть там: app \ code \ vendor \ module \ Model \ ResourceModel \ AbstractCollection.php

protected function performAfterLoadBlog($tableName, $columnName) {
    $items = $this->getColumnValues($columnName);
    if (count($items)) {
        $connection = $this->getConnection();
        $select = $connection->select()->from(['blog_entity_store' => $this->getTable($tableName)])
            ->where('blog_entity_store.' . $columnName . ' IN (?)', $items);
        $result = $connection->fetchPairs($select);
        if ($result) {
            foreach ($this as $item) {
                $entityId = $item->getData($columnName);
                if (!isset($result[$entityId])) {
                    continue;
                }
                if ($result[$entityId] == 0) {
                    $stores = $this->storeManager->getStores(false, true);
                    $storeId = current($stores)->getId();
                    $storeCode = key($stores);
                } else {
                    $storeId = $result[$item->getData($columnName)];
                    $storeCode = $this->storeManager->getStore($storeId)->getCode();
                }
                $item->setData('_first_store_id', $storeId);
                $item->setData('store_code', $storeCode);
                $item->setData('store_id', [$result[$entityId]]);
            }
        }
    }
}

protected function joinStoreRelationTable($tableName, $columnName) {
        if ($this->getFilter('store')) {
            $this->getSelect()->join(
                ['store_table' => $this->getTable($tableName)],
                'main_table.' . $columnName . ' = store_table.' . $columnName,
                []
            )->group(
                'main_table.' . $columnName
            );
        }
        parent::_renderFiltersBefore();
    }

\ Приложение \ индекс \ поставщика \ модуль \ модели \ ResourceModel \ Блог \ Collection.php

protected function _afterLoad()  {
    $this->performAfterLoadBlog('vendor_module_store', 'blog_id');
    $this->_previewFlag = false;

    return parent::_afterLoad();
}

protected function _renderFiltersBefore() {
    $this->joinStoreRelationTable('vendor_module_store', 'blog_id');
}

Итак, мой вопрос, как мне идти отсюда, чтобы столбец store_id мог отображаться с правильными представлениями магазина?


Покажите свой код класса коллекции.
Сохель Рана

Модуль очень похож на модуль страниц CMS. Я скопировал функцию из \ app \ code \ vendor \ module \ Model \ ResourceModel \ AbstractCollection.php, которая, как мне кажется, возвращает коллекцию для сетки, включая store_id. Хотя я в некотором роде новичок, поэтому могу ошибаться.
Solide

Коллекция может обрабатывать одну таблицу (по умолчанию). Если вам нужно присоединиться к другой таблице, вам нужно работать с '_afterLoad', '_renderFiltersBefore' и, наконец, добавить карту.
Сохель Рана

Хорошо, я уже получил _afterload и _renderFiltersBefore (я редактировал вопрос). Не уверен, что я уже добавил карту, не могли бы вы уточнить это? Заранее спасибо.
Solide

@ Solide, ты решил эту проблему?
Прашант Валанда

Ответы:


1

Наконец-то я решил эту проблему. Оказалось, что у меня было две коллекции, доступные для моей сетки, и та, которая была загружена, не содержала индекс store_id. Для получения дополнительной информации о двойных коллекциях см .: Magento 2: Почему для компонента листинга пользовательского интерфейса нужны две коллекции?

Чтобы решить эту проблему, я отредактировал конфигурацию внедрения зависимостей в /app/code/vendor/module/etc/di.xml

Здесь я заменил это:

<virtualType name="Vendor\Module\Model\ResourceModel\Blog\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
<arguments>
    <argument name="mainTable" xsi:type="string">vendor_module_blog</argument>
    <argument name="resourceModel" xsi:type="string">Vendor\Module\Model\ResourceModel\Blog</argument>
</arguments>

с этим:

<type name="Vendor\Module\Model\ResourceModel\Blog\Grid\Collection">
<arguments>
    <argument name="mainTable" xsi:type="string">vendor_module_blog</argument>
    <argument name="eventPrefix" xsi:type="string">module_blog_grid_collection</argument>
    <argument name="eventObject" xsi:type="string">module_grid_collection</argument>
    <argument name="resourceModel" xsi:type="string">Vendor\Module\Model\ResourceModel\Blog</argument>
</arguments>

Это гарантирует, что моя коллекция из app \ code \ vendor \ module \ Model \ ResourceModel \ AbstractCollection.php используется для сетки, и теперь store_id с представлением магазина работает.


Здравствуйте @ Solide, Пожалуйста, ответьте, если есть идея: magento.stackexchange.com/questions/268344/…
akgola
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.