rails中使用ajax

来源:互联网 发布:linux搭建hadoop 编辑:程序博客网 时间:2024/06/08 19:35

最近在做一个博客网站,文章编辑器使用的是markdown语法解析,解析方法使用到一个helper方法markdown @article.content,所以内部的编辑器实际上就是一个textarea,没有其他工具,看上去光秃秃的,所以我想给它添加点小工具,方便使用。而第一个要添加的工具就是预览功能。

我的想法是这样的:首先预先创建一个<div id="preview-text"></div>,然后将其设置为display:none。剩下要做的就是当用户点击预览按钮时,将动态获取textarea的内容,并将其传递给rails的markdown方法进行渲染,将渲染结果输出到div#preview-text。使用jquery的slideDown()slideUp()函数可以很好的控制div#preview-text的显示和隐藏。而获取textarea的内容的解决方案,目前也只能靠js完成。于是剩下的问题就很明了了,即如何将js获取的textarea的内容传递给rails的markdown函数。一个突出的问题是,js不能使用rails的函数;rails在erb模板中可以获得js变量,但其在不刷新页面的情况下,只能解析一次(erb只能保存静态变量,无法保存动态变量,即erb在编译后其所定义的变量就不变了)。于是最好的办法就只能是ajax了(js获取内容传递给服务器,服务器(rails)解析后,js获取解析后的内容,异步加载到div#preview-text)。

但rails中如何使用ajax呢?

rails对ajax做了很好的封装,我们可以更加方便的在rails中使用ajax。

首先要构建一个请求,链接,表单等都可以充当一个发送请求的入口。以链接为例:

<%= link_to 'ajax',deal_ajax_path(text:"text"),remote:true,method: :post %><%# 路由需自己设计 %>

注意一定要有remote:true这代表你将向那个url发送一个远程请求而不是转到那个目标url去。
此时在对应的controller中就可以获取params[:text]然后返回json信息。

def preview  @preview_text = markdown(params[:text])  respond_to do |format|      if @preview_text        format.js {}        format.json { render json: @preview_text  , status: :success, location: @preview_text }      else        format.json { render json: @preview_text, status: :unprocessable_entity }      end  endend

由于之前的访问是remote:true所以会返回json格式的数据,在rails中会自动寻找对应action名的模板进行渲染,在这里是preview.js.erb(自行创建)
preview.js.erb中可以使用js:

$("#preview_text").html("<%= escape_javascript(@preview_text) %>");

至此,ajax所需的所有工作都已做完了。
对于一般的需求,到这就为止了,但有个问题,即传递的text该在哪设置。上文作为演示,在url后加上了一个固定的文本,但我要做的是实时获取textarea域的文本。我第一次想到的方案是,当用户点击预览按钮,使用js动态设置url的参数。这有个问题,即用户点击一次后,在html中就会保留上次动态在url后添加的文本参数,该参数将非常长,很不美观。因此我使用了第二种方法:丢弃rails提供的remote方式,自行用js构造请求:

$(document).on("click","#tool-preview",function(event){      preview_text = $("#preview_text").val();      $.post("/admin/mdtools/preview",      {        text:preview_text      },function(data,status){        if(...){          $("#preview_text").slideDown("fast");        }else{          $("#preview_text").slideUp("fast");        }      })})

至此终于达到我的预期功能。

预览前:

picture

预览后:

picture

1 0
原创粉丝点击