JavaScript Ruby-on-Rails не загружается на link_to

Я использую визуализацию Google для создания таблицы диаграмм в теге скрипта, вложенном в представление. Это работает достаточно хорошо, когда страница извлекается напрямую, но при запуске через помощника link_to javascript не работает.

Я полагаю, что это было связано с турбоссылками, однако обертывание JavaScript, как показано ниже, с помощью page:load не имело значения. Я подтвердил, что отключение турболинков решает эту проблему, однако без них все приложение работает значительно медленнее.

<script  type="text/javascript" charset="UTF-8">
    function resultstable () {
        google.load('visualization', '1', {packages:['table']});
          google.setOnLoadCallback(drawTable);
          function drawTable() {
           var data = new google.visualization.DataTable();
            data.addColumn('string', '');
            data.addColumn('number', 'Lot #');
            data.addColumn('string', 'Client');
            data.addColumn('boolean', 'Commercial');
            data.addColumn('string', 'Site');
            data.addColumn('string', 'Biological Classification');
            data.addColumn('string', 'Actions');
            data.addRows([
                <% @lots.each do |lot| %>
                    [
                    '<%= check_box_tag "lot_ids[]", lot.id %>', 
                    <%= lot.id.to_s %>, 
                    '<%= link_to Client.find(lot.client_id).org.to_s.humanize, client_path(lot.client_id) %>',
                    <%= lot.commercial %>,
                    '<%= lot.site %>',
                    '<%= lot.phylum.to_s + " " + lot.l_class.to_s + " " + lot.genus.to_s + " " + lot.species.to_s %>',
                    '<%= link_to edit_lot_path(lot) do %><i class="icon-edit"></i><% end %> <%= link_to lot_path(lot) do %><i class="icon-time"></i><% end %>'
                    ],
                <% end %>           
            ]);

            function rm_google_classes() {
            var className = 'google-visualization-table-table';
            $('.'+className).removeClass(className);

            var className = 'google-visualization-table-th';
            $('.'+className).removeClass(className);

            var className = 'google-visualization-table-tr-head';
            $('.'+className).removeClass(className);

            var className = 'google-visualization-table-tr-odd';
            $('.'+className).removeClass(className);

            var className = 'google-visualization-table-tr-even';
            $('.'+className).removeClass(className); 

            var className = 'google-visualization-table-td';
            $('.'+className).removeClass(className);  

            var className = 'google-visualization-table-td-number';
            $('.'+className).removeClass(className);  

            var className = 'google-visualization-table-td-bool';
            $('.'+className).removeClass(className);  

            $("#gtable-results table").addClass("table table-condensed"); 
            };

            var table = new google.visualization.Table(document.getElementById('gtable-results'));
              table.draw(data, {allowHtml: true});
              rm_google_classes();

            google.visualization.events.addListener(table , 'sort',
            function(event) {
              rm_google_classes();
            });     
           };
         }

    $(document).ready(resultstable());
    $(document).on('page:load', resultstable());       
</script>

person user2732663    schedule 14.09.2013    source источник


Ответы (2)


API визуализации очень специфичен в отношении того, как он загружается, поэтому, когда вы вызываете google.load внутри другой подобной функции, вам нужно немного изменить структуру загрузки. Этот:

google.load('visualization', '1', {packages:['table']});
google.setOnLoadCallback(drawTable);

необходимо изменить на это:

google.load('visualization', '1', {packages:['table'], callback: drawTable});

Кроме того, ваши обработчики событий выполнены неправильно:

$(document).ready(resultstable());
$(document).on('page:load', resultstable()); 

вызывает функцию resultstable и передает возвращаемое значение функции (в вашем случае null) готовому обработчику событий, который ничего не делает. Если вы хотите, чтобы функция таблицы результатов вызывалась при готовности документа, вам нужно удалить () в конце имени функции:

$(document).ready(resultstable);
$(document).on('page:load', resultstable); 

Кроме того, я бегло просмотрел информацию о турболинках, и, похоже, вы хотите использовать здесь другой подход. Загрузчик Google динамически добавляет тег script в <head> страницы, который не стирается турбоссылками, поэтому вам не нужно продолжать вызывать загрузчик каждый раз, когда вы загружаете новую страницу. Попробуйте это вместо этого:

function drawTable () {
    // table drawing code
}

function init () {
    $(document).on('page:load', drawTable);
    drawTable();
} 
google.load('visualization', '1', {packages:['table'], callback: init});

Это обеспечит загрузку API визуализации и вызов функции drawTable при каждой загрузке страницы.

person asgallant    schedule 14.09.2013
comment
Спасибо! это решило проблему. Есть ли шанс, что вы могли бы объяснить, что происходит с обратным вызовом? - person user2732663; 15.09.2013
comment
Я бы сделал это, если бы мог, но я сам не совсем понимаю, что происходит на заднем плане. Если я правильно помню, у загрузчика есть два пути кода, один для обработки сценариев загрузки во время загрузки страницы, а другой для загрузки сценариев после загрузки страницы, и по какой-то причине второй обрабатывает обратный вызов по-разному. - person asgallant; 15.09.2013
comment
Спасибо. Хорошее решение. Действительно выручил меня. - person gnuchu; 12.02.2015

Одним из решений может быть использование драгоценного камня jquery-turbolinks. В этом случае должно работать событие jQuery ready().

См.: https://github.com/kossnocorp/jquery.turbolinks.

person chucknelson    schedule 14.09.2013