Rails:通过调用Ajax重定向

Rails: redirect with call to Ajax

本文关键字:Ajax 重定向 调用 Rails      更新时间:2023-09-26

我正试图将未登录的用户直接重定向到登录窗口,这是一个引导模式窗口。

我在ApplicationController:中编写了一个名为logged_in_user的方法

def logged_in_user
  unless !current_user.nil?
    flash[:danger] = "Please log in"
    redirect_to root_url
  end
end

login_url路由到sessions#new,我定义如下:

(sessions_controller.rb)
def new
  respond_to do |format|
    format.html
    format.js
  end
end

以下是redirect_to root_url所指向的观点:

  <!-- Login Window -->
  <div id="login-window" class="modal fade" role="dialog" aria-labelledby="login" aria-hidden="true"></div>

以下是调用sessions#new时执行的new.js.erb

$("#login-window").html("<%= escape_javascript(render 'sessions/new') %>");

因此,一旦调用sessions#new,登录表单(即app/views/sessions中的_new.html.erb)将作为弹出窗口出现。

除了它必须被处理为JS而不是HTML。因此,我有以下链接,它位于_header.html.erb中,可用于所有视图,以确保情况确实如此:

<%= link_to "Log in", login_path, {remote: true, 'data-toggle' =>  "modal", 'data-target' => '#login-window'} %>

单击链接时,此操作效果良好。这就是为什么我选择在logged_in_user方法中使用redirect_to root_url而不是redirect_to login_url,因为后者会导致"缺少模板错误"。

但我真正想要的是让用户直接重定向到弹出窗口,而不是先重定向到root_url,然后点击"登录"链接才能进入表单。换句话说,我需要一种方法,通过发出Ajax请求以某种方式将用户重定向到sessions#new,以便sessions#new可以作为JS处理。

我在logged_in_user方法中尝试了以下方法来实现所需的重定向,但都不起作用:

render js: "window.location = <%= escape_javascript(render 'sessions/new') %>"
render js: "window.location = '/sessions/new'"
redirect_to login_url, format: "js"

如有任何建议,我们将不胜感激!

只需添加此

<script type="text/javascript">
  $(document).ready(function() {
  if(window.location.href.indexOf('#login-window') != -1) {
    $('#login-window').modal('show');
  }
});
</script>

redirect_to root_url+"#login-window"

通过修改以下文件解决了此问题:


application_controller.rb

def logged_in_user
  unless !current_user.nil?
    session[:modal] = true
    redirect_to !request.referrer.nil? ? (request.referer + "#login-window") : "#login-window" 
  end 
end

我省略了flash[:danger],因为它显示在褪色的后面屏幕我添加了request.referer,以确保登录弹出窗口显示在用户发出请求的位置,而不是将他们重定向到root_path。我认为这对用户体验会更好。(三进制只是为了处理request.referer可以是nil的情况,在这种情况下,代码会出现错误。)session[:modal] = true背后的基序解释如下。


(位于application.html.erb的底部)

<% if session[:modal] == true %>
  <script type="text/javascript">
    $(document).ready(function() {
      if(window.location.href.indexOf('#login-window') != -1) {
        $('#login-window').modal('show');
        $("#login-window").html("<%= escape_javascript(render 'sessions/new') %>");
      }
    });
  </script>
  <% session[:modal] = false %>
<% end %>

在这里,我直接在视图模板中使用javascript。由于弹出窗口显示的视图模板不限于一个特定的模板,因此我在application.html.erb中编写了适用于所有视图模板的脚本。它的前半部分受到了嘎吱嘎吱的回答的启发。(谢谢你!)然后我添加了$("#login-window").html("<%= escape_javascript(render 'sessions/new') %>");,以确保登录表单(`app/views/sessions/_new.html.erb)确实出现。

现在,由于我希望只有当未登录的用户试图访问需要登录的页面时才会出现登录弹出窗口,所以我继续添加了session[:modal] = true,以表明确实调用了logged_in_user方法,这意味着确实发生了上述情况。

然后,在application.html.erb中,我可以检查弹出窗口是否应该在<% if session[:modal] == true %>之前出现。如果是这种情况,那么将执行脚本,然后我将session[:modal]的值设置为false

这个session[:modal]逻辑可能不是必需的(事实上,没有它它也能正常工作),但我添加了它只是以防万一。


就是这样:)

此外,对于那些想用引导程序实现弹出窗口功能的人来说,这里有一个我发现非常有用的博客:

https://coderwall.com/p/ej0mhg/open-a-rails-form-with-twitter-bootstrap-modals

编码快乐!