本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告
 本博客在此声明所有文章均为转摘,只做资料收集使用。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:1304
评论数量:2242
留言数量:5
访问次数:7578621
建立时间:2006年5月29日




[Ruby on Rails]实现一个auto_redirect_to
软件技术

lhwork 发表于 2007/2/8 10:09:12

最近在使用RoR做项目,体会到了快速开发的乐趣,也遇到了一些困难,其中一个就是redirect_to。我遇到的一个问题是,当使用Ajax更新页面局部内容时,session内容已经过期,这时需要整个页面跳转到登录页面。直接调用redirect_to会使局部内容显示成登录页面,它是在HTTP头里写入重定向参数来实现的。在我这里的特殊情况下,正确的做法是让它执行一个包含在<script>标记中的脚本,在脚本中更改窗口location值来跳转。不过RoR中使用Ajax时,会根据:update参数来决定是使用Updater还是Request。如果使用Updater方式,则应返回一段纯脚本;如果是Request方式,应返回一段包括在<script>标记中的脚本;如果是普通方式,就应该使用原有的redirect_to函数了。因为服务端无法区分使用的是哪种方式来请求,所以简单的做法是每个请求都附加一个参数用来区分,不加参数则是普通请求方式。为了达到这个目的,我修改了prototype_helper中的remote_function函数。这个函数根据传递进来的参数来决定使用Request或是Updater,我就在这里下手: <!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->      def remote_function(options)        javascript_options = options_for_ajax(options)        update = ''        if options[:update] and options[:update].is_a?Hash          update  = []          update << "success:'#{options[:update][:success]}'" if options[:update][:success]          update << "failure:'#{options[:update][:failure]}'" if options[:update][:failure]          update  = '{' + update.join(',') + '}'        elsif options[:update]          update << "'#{options[:update]}'"        end        function = update.empty? ?           "new Ajax.Request(" :          "new Ajax.Updater(#{update}, "            url_options = options[:url]        ajax_options = options[:update] ? {:ajax => 'update'} : {:ajax => 'request'}        url_options = url_options.merge(ajax_options)        url_options = url_options.merge(:escape => false) if url_options.is_a? Hash        function << "'#{url_for(url_options)}'"        function << ", #{javascript_options})"        function = "#{options[:before]}; #{function}" if options[:before]        function = "#{function}; #{options[:after]}"  if options[:after]        function = "if (#{options[:condition]}) { #{function}; }" if options[:condition]        function = "if (confirm('#{escape_javascript(options[:confirm])}')) { #{function}; }" if options[:confirm]        return function      end有红色的2行是我添加的,由于这个编辑器的原因,没有显示成整行红色。这2行的作用是判断是否有:update参数,用它来决定是添加ajax=update还是ajax=request。现在可以实现一个简单的auto_redirect_to了: <!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->  def auto_redirect_to(method, url)    case method    when 'request'      request_redirect_to(url)    when 'update'      update_redirect_to(url)    else      redirect_to(url)    end  end    def request_redirect_to(url)    render :update do |page|      page.redirect_to(url)    end  end    def update_redirect_to(url)    render :inline => <<->EOS      <script language="javascript">      <%=        render :update do |page|          page.redirect_to("#{url_for(url)}")        end      %>      </script>    EOS  end使用helper方式使它能够被include到ApplicationController中就行了。为了不和参数绑得太死,这里把method作为参数由调用者传入。使用方法,以Login Engine为例,它在access_denied中处理跳转。在ApplicationController中重写这个函数: <!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->    def access_denied      auto_redirect_to(params[:ajax], :controller => "/user", :action => "login")      false    end  现在可以测试了。请求可以是普通的(超链接),Updater方式(请求到一个DIV里),Request方式,现在都能够跳转到正确页面。ajax参数通过hack库代码来实现,对于使用者来说基本上是透明的。


阅读全文(2249) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.047 second(s), page refreshed 144764271 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号