Aplikacja rails'owa wywołuje JS po kilka razy[SOLVED]

Witam.

Mam dość nietypowy problem, mianowicie na jednej z podstron posiadam kod javascriptowy. I kiedy wchodzę na stronę po raz pierwszy lub odświeżę kartę przeglądarki wszystko jest ok. Problem pojawia się, kiedy skaczę po podstronach aplikacji i wrócę na tą podstronę. Wtedy uruchamia się ten kod 2 razy, i jeśli będę tak skakał podstrona bez kodu i podstrona z kodem to za każdym razem kod ten będzie mi się wykonywać n + 1 razy. Dodatkowo ten sam kod wykonuje się na innych podstronach chociaż, go tam nie ma. Czy może mi ktoś wyjaśnić, jakim cudem takie rzeczy się dzieją?

<% if @view == "calendar" %>
  <script type="text/javascript">
    $(function(){
      var date;
      $.ajax({
        url: "/get/calendar/date.json",
        dataType: "json",
        async: false,
        success: function(data){
          date = new Date(data["date"]);
        }
      });
      var holidays = [];
      $.ajax({
        url: "/get/holidays.json",
        dataType: "json",
        async: false,
        success: function (data) {
          $.each(data, function (index, holiday) {
            holidays.push({
              title: holiday["employee"]["first_name"] + " " + holiday["employee"]["last_name"],
              start: holiday["start_date"],
              end: holiday["end_date"],
              id: holiday["id"]
            });
          });
        }
      });
      $.ajax({
        url: '/holidays/list.json',
        dataType: "json",
        async: false,
        success: function (data) {
          $.each(data, function (index, holiday) {
            var new_end_date = new Date(Date.parse(holiday.end_time));
            new_end_date.setDate(new_end_date.getDate() - 1);
            holidays.push({
              title: holiday["title"],
              start: holiday["start_time"],
              end: holiday["end_time"],
              backgroundColor: "#F00"
            });
          });
        }
      });

      $('#fullcalendar').removeClass('hidden');
      $('#fullcalendar').fullCalendar({
        viewRender: function () {
          $('div.table-responsive').addClass('hidden');
        },
        firstDay: 1,
        header: {
          left: '',
          center: 'prev, title, next',
          right: ''
        },
        events: holidays,
        eventClick: function (event) {
          if ( event.id ) {
            window.location.href = "/holidays/" + event.id + "/edit";
          }
          else{
            alert("This event is not editable!");
          }
        },
        dayClick: function (day) {
          var date_string = [day.getFullYear(), day.getMonth() + 1, day.getDate()].join('-');
          window.location.href = "/holidays/new?date=" + date_string;
        },
        viewDisplay: function(view){
          var clicked_date = $('#fullcalendar').fullCalendar('getDate');
          var date_string = [add_zeros(clicked_date.getFullYear()), add_zeros(clicked_date.getMonth()+1), add_zeros(clicked_date.getDate())].join('-');
          $.ajax ({
            url: "/set/calendar/date",
            async: false,
            data: { "calendar_date": date_string }
          });
        }
      });

      $('#fullcalendar').fullCalendar('gotoDate', date);
    });
  </script>
Jakiś kod html
<% else %> jakiś inny kod HTML
<% end %>

Dodam jeszcze, że nie następuje w aplikacji żadne przekierowanie. Wygląda to tak jakby za każdym razem javascriptowy kod był przetrzymywany w pamięci podręcznej i kumulował się tam za każdym wejściem na stronę.

Swoim javascriptem dodajesz handlery dla jakichś zdarzeń. Prawdopodobnie masz turbolinki i wygląda to tak:
Wchodzisz na widok -> Twój javascript jest odpalany, dodają się handlery -> klikasz sobie w 2 turbolinkowe linki żeby wrócić -> Twój javascript jest znowu odpalany i te same handlery są dodane drugi raz -> wszystko odpala się dwa razy.

Wyrzuć javascript z widoków do assetów i inicjalizuj jakoś mądrzej, tak żeby się odpalał tylko jak jest jakiś element na stronie szy soś.

2 Likes

Tak jak pisze Kalaf + wyglada na to, ze te wywolania ajaxowe nie zaleza od strony, na ktorej jestes; pierwsze pobiera date, a 2gie definicje ‘świąt’.

Zatem prawdopodobnie moglbys to wywolywac raz, a wyniki przechowywac gdzies w obiekcie ‘window’ albo w obiekcie ‘aplikacji’ pod ‘window’ - jesli faktycznie uzywasz turbolinkow, to zawartosc obiektu powinna byc zachowywana pomiedzy ‘przeladowywaniem’. Czyli taki globalny cache.

1 Like

To było to. Nadziałem się na te turbolinki już nie raz. Dzięki wielkie.