Как обеспечить корректную работу $ajax + turbolinks Rails 4.1?

Доброго времени суток! Никак не могу разобраться как бороться с новым суеркрутым механизмом turbolinks. Сразу скажу, что отключение turbolinks легко и просто решает проблему, но мы не ищем легких путей, да и фича крутая - не хотелось бы ее лишаться из-за такой проблемы.
Идея: Каждый промежуток времени (например, 500мс) отправляем запрос на сервер. В ответ получаем JSON и уже с ним работаем.
Проблема: js код разместил в парциале бокового меню (знаю что вообще-то есть coffee скрипт и т.д. Прошу тапками пока не кидать). Но при переходе по ссылкам где этого бокового меню и в помине нет, запросы продолжают генерироваться. А если ходить по ссылкам, где боковое меню есть, то количество запросов увеличивается пропорционально количеству посещенных страниц. Соответственно обновление страницы решает проблему.
Вопрос: Как победить проблему? Перенести js код куда-либо? Или заюзать гем jQuery.turbolinks (пробовал, но эффекта не было)?
Код:
setInterval(function(){
    $.ajax({
        type: "POST",
        url: "/sidebar",
        data: "user=" + <%= current_user.id %> + "&cpe=" + <%= @cpe_instance.id %>,
        success: function(msg){
            if (msg.error == "no") {
                console.log("Some message here...");
            }
            else {
                console.log(msg.error);
            }
        }
    });
}, 500);

Заранее спасибо всем откликнувшимся за помощь!
  • Вопрос задан
  • 4175 просмотров
Решения вопроса 2
AMar4enko
@AMar4enko
Ну ешкин кот, понятно же, что турболинки херовы каждый раз вытаскивают вместе с хэтэмээль ваш жабоскрипт и jquery его исполнительно запускает. А раз страница не обновляется, то и интервалы ваши никуда не деваются и накапливаются.
Вот тут куча всяких разных событий, которыми турболинки стрелят - я советую вам на page:load повесить создание вашего многострадального интервала, а на page:fetch его очистку.
setInterval возвращает id, по которому его можно удалить. Это я так. на всякий случай.
Ответ написан
viktorvsk
@viktorvsk
1. Ясное дело, что document у вас один, событие, каждый раз как вы загружаете страницу вы навешиваете на него событие с вызовом функции alert(), но нигде его не убираете. Можно попробовать при page:load убирать события с документа. Можно вешать интервал на переменную, и проверять, если переменная уже существует, то не выполнять код, если нет - навесить на нее интервал

2. Можно посмотреть в сторону data-no-turbolink и вынести скрипт и хед. Кстати, хед вообше не должен грузиться. Если грузится - вообще что-то не так делаете.

3. Самое верное решение. Прочитать про плюсы и минусы турболинка, pjax и "стратегии оптимистической загрузки", почитать 14 best practices yahoo, посмотреть как работает гугл и как он разивает свою библиотеку (там даже нет события ready) и выкинуть нафик турболинк. Как сказал кто-то при релизе 4 рельс (не устаю напоминать): "4 рельсы - замечательные. Но первым делом что нужно сделать, это удалить gem 'turbolinks' из Gemfile"
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@Farades Автор вопроса
Всем спасибо! Вот решение вопроса:
var new_timer;

$(document).on('ready page:load', function () {
    if (typeof new_timer != 'undefined') {
        clearInterval(new_timer);
        add_timer();
    }
    else {
        add_timer();
    }
});

$(document).on('page:fetch', function () {
    clearInterval(new_timer)
});

function add_timer() {
    new_timer = setInterval(function(){
    $.ajax({
        type: "POST",
        url: "/sidebar",
        data: "user=" + <%= current_user.id %> + "&cpe=" + <%= @cpe_instance.id %>,
        success: function(msg){
            if (msg.error == "no") {
            console.log("Some message");
            }
            else {
                console.log(msg.error);
            }
        }
    });
    }, 500);
}
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы