@by_steris

Как решить проблему с дублированием при ajax?

Столкнулся с проблемой работы ajax в комплексном компоненте news.
Что происходит на странице расположен комплексный компонент новостей и у него есть smart.filter, сам компонент работает в режиме ajax, также фильтр срабатывает моментально, добавил функцию в шаблон news.list и переписал стандартный компонент навигации для того чтобы подгрузка контента была также ajax'овая. Но при использовании фильтра, а затем подгрузки контента через навигацию подгруженные элементы на странице дублируются.
Если например применить фильтр, затем обновить страницу и нажать кнопку "Показать еще", то данной проблемы нет

Шаблон списка новостей:
<? if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
/** @var array $arParams */
/** @var array $arResult */
/** @global CMain $APPLICATION */
/** @global CUser $USER */
/** @global CDatabase $DB */
/** @var CBitrixComponentTemplate $this */
/** @var string $templateName */
/** @var string $templateFile */
/** @var string $templateFolder */
/** @var string $componentPath */
/** @var CBitrixComponent $component */
$this->setFrameMode(true);
?>

<div class="works-page__body loadmore_wrap">
    <? foreach ($arResult["ITEMS"] as $arItem): ?>
        <?
        $this->AddEditAction($arItem['ID'], $arItem['EDIT_LINK'], CIBlock::GetArrayByID($arItem["IBLOCK_ID"], "ELEMENT_EDIT"));
        $this->AddDeleteAction($arItem['ID'], $arItem['DELETE_LINK'], CIBlock::GetArrayByID($arItem["IBLOCK_ID"], "ELEMENT_DELETE"), array("CONFIRM" => GetMessage('CT_BNL_ELEMENT_DELETE_CONFIRM')));
        ?>
        <a target="_self" href="<?= $arItem['DETAIL_PAGE_URL']; ?>" class="works-page__item loadmore_item"
           id="<?= $this->GetEditAreaId($arItem['ID']); ?>">
            <img src="<?= $arItem['PREVIEW_PICTURE']['SRC']; ?>" alt="<?= $arItem['PREVIEW_PICTURE']['ALT']; ?>"/>
        </a>
    <? endforeach; ?>
</div>

<? if ($arParams["DISPLAY_BOTTOM_PAGER"]): ?>
    <?= $arResult["NAV_STRING"] ?>
<? endif; ?>

<script>
    $(document).ready(function () {
        $(document).on('click', '.load_more', function () {
            var targetContainer = $('.loadmore_wrap'), //  Контейнер, в котором хранятся элементы
                url = $('.load_more').attr('data-url'); //  URL, из которого будем брать элементы
            if (url !== undefined) {
                $.ajax({
                    type: 'GET',
                    url: url,
                    dataType: 'html',
                    success: function (data) {
                        //  Удаляем старую навигацию
                        $('.load_more').remove();
                        var elements = $(data).find('.loadmore_item'), //  Ищем элементы
                            pagination = $(data).find('.load_more'); // Ищем навигацию
                        targetContainer.append(elements); // Добавляем посты в конец контейнера
                        targetContainer.after(pagination); // Добавляем навигацию следом
                    }
                })
            }
        });
    });
</script>


Шаблон навигации:
<? if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
/** @var array $arParams */
/** @var array $arResult */
/** @global CMain $APPLICATION */
/** @global CUser $USER */
/** @global CDatabase $DB */
/** @var CBitrixComponentTemplate $this */
/** @var string $templateName */
/** @var string $templateFile */
/** @var string $templateFolder */
/** @var string $componentPath */
/** @var CBitrixComponent $component */
$this->setFrameMode(true);
?>

<? if ($arResult["NavPageCount"] > 1): ?>
    <? if ($arResult["NavPageNomer"] + 1 <= $arResult["nEndPage"]): ?>
        <?
        $plus = $arResult["NavPageNomer"] + 1;
        $url = $arResult["sUrlPathParams"] . "PAGEN_1=" . $plus
        ?>
        <div class="works-page__btn btn -dark load_more" data-url="<?= $url ?>" style="cursor: pointer">
           <span>Показать еще</span>
        </div>
    <? endif ?>
<? endif ?>


Дополнительно вызов news.list в файле news.php обернул вот таким условием:
<?if($_REQUEST["AJAX_CALL"] == "Y") {
                global $APPLICATION;
                $APPLICATION->RestartBuffer();
            }?>
//вызов news.list
<?if($_REQUEST["AJAX_CALL"] == "Y") {
                die();
            }?>
  • Вопрос задан
  • 93 просмотра
Решения вопроса 1
а Вы не пробовали убрать этот инлайновый скрипт в script.js шаблона? Я считаю, что у Вас в data прилетает этот javascript, исполняется, и становится 2 обработчика $(document).on('click', '.load_more',..) , на следующей подгрузке три и так далее. Это можно увидеть в DevTools - посмотрев, сколько ajax запросов порождает нажатие кнопки
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы