1.
这篇文章还是关于AJAX的,算是一个复习把。
这里,我们将要加入一些AJAX功能到一个站点,其中将使用RJS模板。使用RJS是模板是实现AJAX效果的最简单的方法,特别是你需要更新一个页面的多个元素的时候。
在我们的产品页面,用户能够通过一个表格添加评论,当这个表格以HTTP POST方式提交到服务器的时候,服务器处理表格之后render这个页面给浏览器,从而这个页面重新载入。
{这里插入一点render方法的介绍:
模板在哪里: render方法会到template_root全局配置项所指定的目录中去寻找模板文件,--默认情况下,它位于app/views目录下。这个目录又含有子目录,每个子目录对应一个控制器,其中是该控制器需要的视图模板。模板文件的名字与控制器中各个action的名字一一对应。
当然,模板文件也可以不和action对应,只要在控制器中直接调用render()方法就可以渲染这些模板。render有三种使用方式
例如: render(:action => "fake_action_name")
render(:template => 'controller/name')
render(:file => 'dir/template')
[color=green]其中,第一种方式是指向同一个controller中一个action的名字,但是并不会执行这个action,而是直接调用这个action对应的模板,而当前网址也不会改变成这个action的名字,这是与redirect_to的区别[/color]
第二种方式指向另外一个controller中的一个action
第三种方式指向任何一个地方的某个文件,如果你想在多个应用程序之间共享某个视图,这就是一种好的方式}
好了,继续我们前面的AJAX话题,在返回的页面中,有多个元素与提交之前相比发生了变化:
a. 显示当前有多少条评论的数字发生了变化
b. 新的评论加了进去
c. 表格被清空
d. 有一个flash message显示在最上面,来谢谢用户添加了评论。
所有这些变化,我们将要使用AJAX和RJS模板来完成。
2. 修改view
在我们修改view页面的代码之前,我们首先要确定我们已经把prototype和其他的标准的javascript 文件包含进了view中,因为AJAX要用到这些javascript库,为此,我们需要在我们的模板中加入如下一行:
ok,我们可以开始修改view了,当前,我们的view中有一个标准的表格:
这里我们需要做的修改就是使这个form通过AJAX方式提交到服务器,而不是普通的HTTP POST方式。因此我们要用form_remote_for 替换掉form_for. (Rails提供了很多方法来将正常的元素转化成AJAX方式的元素,具体这里就不介绍了,因为我也不知道还有其他什么方法)
如果浏览器关掉了javascript,那么这个form仍然会工作,只是提交的时候是普通的HTTP POST方式。
做了这个修改之后,我们可以刷新一下我们的页面,在console,我们会看到render到浏览器的部分是这样的:
def create
@review = Review.new(params[:review])
@review.product_id = params[:product_id]
@review.save
flash[:notice] = "Thank you for your review"
redirect_to product_path(params[:product_id])
end
[/code]
redirecting won't work with an AJAX request, 所以这里要修改,改成根绝接收到的是HTTP POST还是javascript request,来决定返回什么, respond_to 这个方法就是做这个的,这个方法接收一个block, 我们把不同的返回结果放在block里面
好了,如果是js,我们什么也没有定义,那么默认的就会返回RJS模板,下面我们就创建这个RJS 模板。
4. Create RJS 模板
模板的名字是 create.rjs,因为他对应的是create action,并且在收到js请求而不是普通的html请求时候,才会被调用。这个rjs文件将会生成javascript, 并将其返回给浏览器执行,这就是对AJAX的响应。
在这个模板中,首先我们要添加这个新的review到list中,所有的review是按照id顺序被render的, 每一个review通过一个partial叫做 _review.html.erb来render,
下面详细介绍一下各个参数:
Where to insert the HTML (this can be :before, :after, :top or :bottom).
The id of the element we want to modify (our ‘reviews’ list).
The HTML to render. This can be as simple as a string, or, in our case, a partial. We pass the name of the partial and the object to pass to it. (In Rails 2.3 this can be shortened to :partial => @review).
ok,我们已经添加了新的评论,但是现在有多少条评论的数字还没有更新,我们在加入一行rjs code来完成这个任务。这一次,我们使用replace_html这个方法,而不是insert_html方法,因为我们在replace,而不是insert。
下面该介绍replace_html这个方法了,他接收id of the element we want to update 作为第一个参数,然后第二个参数是新的内容,我们这里我们没有@product变量了,因为这次交流的controller实例中没有出现@product, 所以我们只能使用@review.product
还有一个工作,reset the form.
最好,show the flash notice:
一切顺利,但是还有一个问题,就是下次刷新的时候,flash不会消失,这个flash的工作机制决定的,他会一直保持到下一次request.
解决方法很简单,在rjs中,将flash 送到浏览器后,清空flash就可以了。
这篇文章还是关于AJAX的,算是一个复习把。
这里,我们将要加入一些AJAX功能到一个站点,其中将使用RJS模板。使用RJS是模板是实现AJAX效果的最简单的方法,特别是你需要更新一个页面的多个元素的时候。
在我们的产品页面,用户能够通过一个表格添加评论,当这个表格以HTTP POST方式提交到服务器的时候,服务器处理表格之后render这个页面给浏览器,从而这个页面重新载入。
{这里插入一点render方法的介绍:
模板在哪里: render方法会到template_root全局配置项所指定的目录中去寻找模板文件,--默认情况下,它位于app/views目录下。这个目录又含有子目录,每个子目录对应一个控制器,其中是该控制器需要的视图模板。模板文件的名字与控制器中各个action的名字一一对应。
当然,模板文件也可以不和action对应,只要在控制器中直接调用render()方法就可以渲染这些模板。render有三种使用方式
例如: render(:action => "fake_action_name")
render(:template => 'controller/name')
render(:file => 'dir/template')
[color=green]其中,第一种方式是指向同一个controller中一个action的名字,但是并不会执行这个action,而是直接调用这个action对应的模板,而当前网址也不会改变成这个action的名字,这是与redirect_to的区别[/color]
第二种方式指向另外一个controller中的一个action
第三种方式指向任何一个地方的某个文件,如果你想在多个应用程序之间共享某个视图,这就是一种好的方式}
好了,继续我们前面的AJAX话题,在返回的页面中,有多个元素与提交之前相比发生了变化:
a. 显示当前有多少条评论的数字发生了变化
b. 新的评论加了进去
c. 表格被清空
d. 有一个flash message显示在最上面,来谢谢用户添加了评论。
所有这些变化,我们将要使用AJAX和RJS模板来完成。
2. 修改view
在我们修改view页面的代码之前,我们首先要确定我们已经把prototype和其他的标准的javascript 文件包含进了view中,因为AJAX要用到这些javascript库,为此,我们需要在我们的模板中加入如下一行:
<%= javascript_include_tag :defaults%>
ok,我们可以开始修改view了,当前,我们的view中有一个标准的表格:
<%form_for [@product, @review] do |form|%>
<ol class="formList">
<li><%=form.label :name, "Name:"%><%=form.text_field :name%></li>
<li><%=form.label :content, "Review:"%><%=form.text_area :content, :rows => 5%></li>
<li><%=submit_tag "Add comment"%></li>
</ol>
<%end%>
这里我们需要做的修改就是使这个form通过AJAX方式提交到服务器,而不是普通的HTTP POST方式。因此我们要用form_remote_for 替换掉form_for. (Rails提供了很多方法来将正常的元素转化成AJAX方式的元素,具体这里就不介绍了,因为我也不知道还有其他什么方法)
如果浏览器关掉了javascript,那么这个form仍然会工作,只是提交的时候是普通的HTTP POST方式。
做了这个修改之后,我们可以刷新一下我们的页面,在console,我们会看到render到浏览器的部分是这样的:
<form action="/products/1/reviews" class="new_review" id="new_review" method="post"
onsubmit="new Ajax.Request('/products/1/reviews',
{asynchronous:true, evalScripts:true, parameters:Form.serialize(this)});
return false;”>
可以看到,有一个onsubmit事件,这就是为什么要浏览器打开javascript才能实现AJAX效果的原因。
3. 修改controller
review 里面的表格被提交到了一个叫做create的action(在reviews controller中), 这个action将添加这个review到数据库,设置一个flash notice,并重定向到product page.
[code="java"]
def create
@review = Review.new(params[:review])
@review.product_id = params[:product_id]
@review.save
flash[:notice] = "Thank you for your review"
redirect_to product_path(params[:product_id])
end
[/code]
redirecting won't work with an AJAX request, 所以这里要修改,改成根绝接收到的是HTTP POST还是javascript request,来决定返回什么, respond_to 这个方法就是做这个的,这个方法接收一个block, 我们把不同的返回结果放在block里面
respond_to do |format|
format.html {redirect_to product_path(params[:product_id])}
format.js
end
好了,如果是js,我们什么也没有定义,那么默认的就会返回RJS模板,下面我们就创建这个RJS 模板。
4. Create RJS 模板
模板的名字是 create.rjs,因为他对应的是create action,并且在收到js请求而不是普通的html请求时候,才会被调用。这个rjs文件将会生成javascript, 并将其返回给浏览器执行,这就是对AJAX的响应。
在这个模板中,首先我们要添加这个新的review到list中,所有的review是按照id顺序被render的, 每一个review通过一个partial叫做 _review.html.erb来render,
insert_html :bottom, :reviews, :partial=>'review', :object=>@review
下面详细介绍一下各个参数:
Where to insert the HTML (this can be :before, :after, :top or :bottom).
The id of the element we want to modify (our ‘reviews’ list).
The HTML to render. This can be as simple as a string, or, in our case, a partial. We pass the name of the partial and the object to pass to it. (In Rails 2.3 this can be shortened to :partial => @review).
ok,我们已经添加了新的评论,但是现在有多少条评论的数字还没有更新,我们在加入一行rjs code来完成这个任务。这一次,我们使用replace_html这个方法,而不是insert_html方法,因为我们在replace,而不是insert。
page.replace_html :review_count, pluralize(@review.product.reviews.size, 'Review')
下面该介绍replace_html这个方法了,他接收id of the element we want to update 作为第一个参数,然后第二个参数是新的内容,我们这里我们没有@product变量了,因为这次交流的controller实例中没有出现@product, 所以我们只能使用@review.product
还有一个工作,reset the form.
page[:new_review].reset
最好,show the flash notice:
page.replace_html :notice, flash[:notice]
一切顺利,但是还有一个问题,就是下次刷新的时候,flash不会消失,这个flash的工作机制决定的,他会一直保持到下一次request.
解决方法很简单,在rjs中,将flash 送到浏览器后,清空flash就可以了。
flash.discard