2014-01-16 7 views
0

У меня есть приложение Ruby on Rails с некоторым jquery для рендеринга частичных асинхронно. Поэтому сначала я хочу, чтобы изменить активное состояние вкладок, затем очистить вкладки, а затем загрузить парциальное:Выполнение операторов jquery последовательно

$('#availability').addClass('active'); 
    $('#overview').removeClass('active'); 
    $('#availabilityTab').addClass('active').addClass('in'); 
    $('#overviewTab').removeClass('active').removeClass('in'); 
    $("#availabilityTab").html("<%= escape_javascript(render(partial: 'availability')) %>"); 

Это прекрасно работает, однако при нажатии на вкладку, чтобы вызвать это, я ожидал увидеть пустую закладку и загруженные данные. Что происходит, когда нажата вкладка, ничего не происходит, и через 3 секунды появляются частичные. Это связано с тем, что вызов базы данных занимает некоторое время (необходимо оптимизировать :-)). Это смущает для пользователя, я скорее хочу сначала увидеть пустую закладку. Как я могу это сделать?

Update: Это как действие контроллер выглядит следующим образом:

def index 
    @customers = Customer.order(:name) 
    @target = params[:target] unless params[:target].blank? 

    respond_to do |format| 
     format.html 
     format.js 
    end 
    end 

И это index.js.erb:

<% if @target == "overview" -%> 
    $('#availability').removeClass('active'); 
    $('#overview').addClass('active'); 
    $('#overviewTab').addClass('active').addClass('in'); 
    $('#availabilityTab').removeClass('active').removeClass('in'); 
    $("#overviewTab").empty().html("<%= escape_javascript(render(partial: 'overview')) %>"); 
<% elsif @target == "availability" -%> 
    $('#availability').addClass('active'); 
    $('#overview').removeClass('active'); 
    $('#availabilityTab').addClass('active').addClass('in'); 
    $('#overviewTab').removeClass('active').removeClass('in'); 
    $("#availabilityTab").html("<%= escape_javascript(render(partial: 'availability')) %>"); 
<% end %> 
+0

Возможно, попробуйте скрыть элемент до полной загрузки? проверьте здесь http://stackoverflow.com/questions/3452226/jquery-hide-div-until-fully-loaded – Meow

+0

Может быть, это не видно, пока оу не разместит контент? Затем вы должны установить фиксированную ширину и высоту для вкладки –

+0

Вы используете 'async: false' правильно? –

ответ

0

Кажется мне, что вы используете async: false в Ajax (это замерзает браузер пока запрос не будет завершен)

Даже если это не так, ваши эффекты зависят от вашего вызова db, поэтому вы столкнулись с la г. Чтобы это исправить, вам необходимо либо переконфигурировать систему для работы вокруг Ajax, или вам нужно, чтобы вызвать ваши эффекты как можно более естественно (IE во внутреннем интерфейсе после вызова дб был обработан)

Вот два способа смотреть на него:


Ajax Callbacks

wait for a jquery ajax callback from calling function

Мы успешно используем Ajax Callba CKS загрузить партиалы в одном из наших производственных приложений, вот как мы это делаем:

//app/assets/application.js 
$(".your_element").on("click", function() { 
    fetch_modal("link", function(data){ 
     //success 
    , function(data) { 
     //error 
    }); 
}); 

//Ajax 
function fetch_modal(link, success, error) { 
    $.ajax({ 
     url: link, 
     success: function(data) { success(data); }, 
     error: function(data) { error(data); } 
    }); 
} 

Это не замерзнет браузер, и работает синхронно

У меня есть скрипт, который вызывает партиалы через Ajax, используя эту технику, если вам нужна ссылка. Я был смысл, чтобы опубликовать его


Обработка После ДБ Позвоните

Одна из причин, которые вы видите эти проблемы, если вы звоните в JS после события, а не результат

Чтобы исправить это, я смотреть на ввод «эффект» код после того, как JS был обработан, как это:

#app/controllers/example_controller.rb 
def example 
    @example = Example.find(1) 

    respond_to do |format| 
     format.html { redirect_to root_path } 
     format.js 
    end 
end 

#app/views/example/example.js.erb 
# Only fires after the DB call 
$('#availability').addClass('active'); 
$('#overview').removeClass('active'); 
$('#availabilityTab').addClass('active').addClass('in'); 
$('#overviewTab').removeClass('active').removeClass('in'); 
$("#availabilityTab").html("<%= escape_javascript(render(partial: 'availability')) %>"); 
+0

Спасибо за ваш исчерпывающий ответ!Мне нравится второе решение, но я действительно не понимаю, что вы имеете в виду под «# Только пожары после вызова БД». Мне кажется, что строки jquery-кода точно такие же, как у меня? Я уточнил свой вопрос с дополнительной информацией. – John

+0

Hey John - Я имел в виду, что он срабатывает только после того, как Rails выполнил его запрос, а не когда вы выполнили событие в JS. Другое дело, что после запроса будет означать, что ваше приложение покажет значок «загрузка» до тех пор, пока выполняется запрос, а затем применяются разные классы –

Смежные вопросы