在 Rails 2.2 项目中,我让用户将项目列表放在一个投资组合对象中(即:)PortfolioHasManyProjects
。页面上有一个用于常规文本、标题等的 Rails 表单,以及 2 个可排序列表;这些列表用于将项目从全局项目列表拖到您的投资组合项目列表中。
它类似于这里所做的:http: //ui.jquery.com/latest/demos/functional/#ui.sortable。
我有投资组合列表 (#drag_list) 更新更改并通过 AJAX 调用提交其序列化数据。 这是在 application.js 文件中完成的:
jQuery.ajaxSetup({
'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
})
jQuery.fn.submitDragWithAjax = function() {
this.submit(function() {
$.post(this.action, $("#drag_list").sortable('serialize'), null, "script");
return false;
})
return this;
};
$(document).ajaxSend(function(event, request, settings) {
if (typeof(AUTH_TOKEN) == "undefined") return;
// settings.data is a serialized string like "foo=bar&baz=boink" (or null)
settings.data = settings.data || "";
settings.data += (settings.data ? "&" : "") + "authenticity_token=" + encodeURIComponent(AUTH_TOKEN);
});
/-------------------------------------------/
$(document).ready(function(){
$(".ajax_drag").submitDragWithAjax();
$("#drag_list").sortable({
placeholder: "ui-selected",
revert: true,
connectWith:["#add_list"],
update : function () {
$("#drag_list").submit();
}
});
$("#add_list").sortable({
placeholder: "ui-selected",
revert: true,
connectWith:["#drag_list"]
});
这就是事情变得棘手的地方。我不确定如何处理序列化数据并将其与表单一起提交给new.html.erb
文件中的控制器。所以我所做的就是new.js.erb
将隐藏的表单字段new.html.erb
与我将在控制器中提取的数据一起插入。
这是 new.js.erb:
$("#projects").html("");
<% r = params[:proj] %>
<% order=1 %>
<% for i in r %>
$("#projects").append("<input type=hidden name=proj[<%=order%>] value=<%=i%> />");
<% order=order+1 %>
<% end %>
编辑new.html.erb:
<h1>New portfolio</h1>
<h2>The List</h2>
<div class="list_box">
<h3>All Available Projects</h3>
<%= render :partial => "projects/add_list" %>
</div>
<div class="list_box">
<h3>Projects currently in your new portfolio</h3>
<%= render :partial => "projects/drag_list" %>
</div>
<div style="clear:both"></div>
<br/>
<br/>
<h2>Portfolio details</h2>
<% form_for(@portfolio) do |f| %>
<%= f.error_messages %>
<h3>Portfolio Name</h3>
<p>
<%= f.text_field :name %>
</p>
<h3>URL</h3>
<p>
<%= f.text_field :url %>
</p>
<h3>Details</h3>
<p>
<%= f.text_area :details %>
</p>
<p>
<div id="projects">
<input type="hidden" name="proj" value="" />
</div>
<%= f.submit "Create" %>
</p>
<% end %>
然后表单提交到投资组合控制器中的 create 方法:
def new
@projects = Project.find(:all)
@portfolio = Portfolio.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @portfolio }
format.js
end
end
def create
@portfolio = Portfolio.new(params[:portfolio])
proj_ids = params[:proj]
@portfolio.projects = []
@portfolio.save
proj_ids.each {|key, value| puts "Key:#{key} , Value:#{value} " }
proj_ids.each_value {|value| @portfolio.projects << Project.find_by_id(value) }
respond_to do |format|
if @portfolio.save
flash[:notice] = 'Portfolio was successfully created.'
format.html { render :action => "index" }
format.xml { render :xml => @portfolio, :status => :created, :location => @portfolio }
else
format.html { render :action => "new" }
format.xml { render :xml => @portfolio.errors, :status => :unprocessable_entity }
end
end
end
所以最后我的问题:
这是这样做的正确方法吗?出于某种原因,我觉得不是,主要是因为在 Rails 中做其他所有事情似乎都更容易和直观。这行得通,但要做到这一点是地狱。必须有一种更优雅的方式通过 AJAX 调用向控制器发送序列化数据。
我将如何在同一页面上调用不同的 AJAX 操作?假设我有一个可排序和一个自动完成的 AJAX 调用,我可以有一个
sortable.js.erb
并autocomplete.js.erb
从任何文件中调用它们吗?我不确定如何设置控制器来对此做出响应。