另一个典型的Ajax功能是现场(In-place)编辑器。如果你是一个Flickr(http://flickr.com)用户,那么你知道可以通过单击想要改变的信息,来编辑自己照片的描述内容及标题。如果你拥有适当的许可,那么文本将转化成一个文本框,允许你在一个页面上查看和编辑数据库的记录,这样使编辑信息的过程既简单又快捷。
你可以用一个名为in_place_editor的简单helper在Rails中实现同样的功能。in_place_editor helper带有一对儿参数:第一个是包含了要更新数据的元素的名字,第二个是一个选项hash,其中最重要的是action的URL,它将接收Ajax的调用。
为了证明这一点,我们将让拥有事件的用户可以在现场编辑事件地址。打开在app/views/events/_event.rhtml中的事件详情局部模板,将下列代码:
<ul>
<li><%=h event.occurs_on %></li>
<li><%=h event.location %></li>
</ul>
替换成源码7-18所示的代码。
源码7-18 添加in_place_editor helper到app/views/events/_event.rhtml
<ul>
<li><%=h event.occurs_on %></li>
<li><span id="event_location_<%= event.id %>"><%=h event.location %></span></li>
</ul>
<%= in_place_editor("event_location_#{event.id}",
:loading_text => "Saving...",
:cancel_text => "Cancel",
:save_text => "Save",
:url => { :action => "update_location",
:id => event }) if event.owned_by? current_user %>
首先我们需要把location项包裹到一个<span>元素中,并赋给它一个特定的id属性,这样它就可以被唯一识别。为了实现这点,我们用一小条ERb将event.id(我们知道它是唯一的)添加到event_location的末尾:
<span id="event_location_<%= event.id %>">
这会使元素id值,如event_location_1和event_location_2。当我们告诉in_place_editor方法要工作在哪个元素上时,做法是一样的:
<%= in_place_editor("event_location_#{event.id}", #...) %>
in_place_editor接受了选项,而这些选项用来自定义显示在提交按钮和取消链接上的文本。我们把它们设成合理的值:Cancel(取消)和Save(保存)。最后,我们用url选项来定义单击Save按钮时,要调用的action。还要注意,我们是如何在调用后,把一个if 修饰符应用到in_place_editor,以确定事件是被当前登录的用户所拥有。这样会有效地使现场编辑只能为事件拥有者所用。
当单击Save按钮时,in_place_editor表单将被序列化并把文本框中的值以参数方式发送到服务器。控制器action需要对值进行处理并在响应中返回更新的值。为了实现这点,我们需要在控制器上创建一个更新action来处理请求,这便是我们下一步要添加的内容。
当用in_place_editor执行update action时,我们需要注意一个特定的惯例:action应被命名为update_field_name,而field_name是要更新的项的名字。因为我们更新的是location项,所以我们的方法将被称为update_location。为events控制器添加update_location action,如源码7-19所示。
源码7-19 在app/controllers/events_controller.rb中添加update_location action
def update_location
Event.update(params[:id], {:location => params[:value]})
render :text => params[:value]
end
这将在使用render :text渲染输入的值之前,把id与params[:id]相匹配的事件更新成改变了的location值——有效地将之前的地址替换成新输入的值。
既然一切都设置好了,那么是时候享受我们的劳动成果了,来看看现场编辑器的工作情况。运行应用程序,重新载入事件列表,并选择一个事件。当你点击事件地址时,它应变成一个文本项,允许你在页面上编辑并保存地址,如图7-8所示。