Javascript 将带有表单数据的GeoJSON数据发布到Rails 4应用程序

Javascript 将带有表单数据的GeoJSON数据发布到Rails 4应用程序,javascript,ruby-on-rails,ajax,post,geojson,Javascript,Ruby On Rails,Ajax,Post,Geojson,我有一个创建“活动”的网页。用户使用简单的表单填写有关活动的一些基本信息: #new.html.erb <%= simple_form_for @activity do |f| %> <%= f.input :name, label: "Activity name", input_html: { id: "create_activity_name_field" }, hint: "At least 7 characters" %> <%= f.inp

我有一个创建“活动”的网页。用户使用简单的表单填写有关活动的一些基本信息:

#new.html.erb
<%= simple_form_for @activity do |f| %>
    <%= f.input :name, label: "Activity name", input_html: { id: "create_activity_name_field" }, hint: "At least 7 characters" %>
    <%= f.input :type, label: "Activity type", input_html: { id: "create_activity_type_field" }, as: :select, :include_blank => false, collection: Activity.types.keys.to_a %>
    <%= f.input :date_field, input_html: { id: "create_activity_date_field" }, as: :string %>
    <%= f.input :time_field, input_html: { id: "create_activity_time_field" }, as: :string %>
    <% f.button :submit, :class => "btn btn-primary" -%>
<% end %>
#new.html.erb
false,集合:Activity.types.keys.to_a%>
“btn btn主节点”-%%>
但是,我也使用MapBox来显示地图。用户将单击地图上的点以创建活动路线。当用户绘制完路由后,我可以提取该路由的GeoJSON数据

我想使用javascript发布GeoJSON数据和表单数据。在后端,我将让rails将GeoJSON转换为KML文件,并使用回形针将其上传到AmazonS3。剩下的数据可以保存,回形针会给我一个指向KML文件的URL,我可以将其与活动关联

我是一个铁路迷,我不知道该怎么做,也找不到任何东西让我越过这个障碍。我考虑过使用javascript的FormData。我非常喜欢这种方法,因为实现看起来非常简单,但显然它只能处理键/值对,而不能处理复杂的嵌套JSON数据


非常感谢任何建议或策略。如果有人能给出详细的答案,我将不胜感激,因为正如我所说,我对rails和web开发还不熟悉。

这里您可能想做的是防止表单在JS中使用默认行为:

$('form').submit(function(e) { 
 e.preventDefault();
 var form = $('form');
 var form_data_json = JSON.stringify(form.serializeArray());
 form_plus_geojson = form_data_json.concat(Geojson);
在JS中获取数据(这应该很容易,但您并没有说如何从mapbox中提取数据)

然后通过AJAX发回数据(不要忘记两端的验证)

发送数据后,您希望恢复正常的表单提交post行为并提交表单

         complete: function() { 
            this.off('submit');
            this.submit();
         }
     });
 }
}))

然后,您只需要解析控制器中的数据

def post_controller
  if request.xhr?
    my_hash = JSON.parse(params[:mydata]) 
  else 
    normal post behavior 
  end
end
一切都是快速的伪代码,您可能需要修复一些东西,因为我还没有测试过它,但它应该可以工作。
显然,现在我们在ajax中做所有事情,您不需要complet函数回调,可以删除该部分。

感谢@jDay为我指明了正确的方向——特别是连接JSON数据。然而,我无法在我的应用程序上使用他的具体解决方案,于是我尝试了另一种方法,在我看来,这种方法更简单一些

我使用Rails simple_form_for gem制作表单,指定了一个远程post调用:

#new.html.erb
<%= simple_form_for @activity, :url => '/activities', :method => :post, :remote => true, html: {id: :activity_create_form, "data-type" => :json} do |f| %>
    <%= f.input :name, label: "Activity name", input_html: { id: "create_activity_name_field" }, hint: "At least 7 characters" %>
    <%= f.input :type, label: "Activity type", input_html: { id: "create_activity_type_field" }, as: :select, :include_blank => false, collection: Activity.types.keys.to_a %>
    <%= f.input :date_field, input_html: { id: "create_activity_date_field" }, as: :string %>
    <%= f.input :time_field, input_html: { id: "create_activity_time_field" }, as: :string %>
    <%= f.button :submit, :class => "btn btn-primary", input_html: {id: "create_activity_submit_btn"} -%>
<% end %>
您将得到您的GeoJSON哈希:

{“类型”=>“特征”,“属性”=>{}, “几何体”=>{“类型”=>“线串”, “坐标”=>[[-118.42014223337173,33.98407904797006], [-118.37825685739517,33.9561751601826]}


但是对于两个post请求,我要处理两个独立的控制器操作,不是吗?这使得后端代码非常粗糙。但是我喜欢你关于将geojson与post-json连接起来的想法。我会研究如何促进这一点。不,不太可能。在rails中,您可以在同一控制器上处理多种数据类型。这是非常普遍的,而且有很多种方法。这里有一个:
if request.xhr?处理json数据,否则正常的post行为结束
我的意思是,我的控制器操作首先必须在没有表单数据的情况下处理geojson。但我不想在不知道表单数据的情况下将geojson存储在模型中。因此,我必须找到一种方法暂时保留它,直到控制器收到表单数据,然后验证并保存所有内容。实际上,您可以连接两个json对象,并使用ajax发送它们。使用jsonArray1=jsonArray1.concat(jsonArray2);并将其作为数据传递。应该行的。我正在编辑我的答案。另外,为了回答您的问题,您可以创建一个新实例,并且只在表单数据存在时保存它。但是再也不需要了。
#new.html.erb
<%= simple_form_for @activity, :url => '/activities', :method => :post, :remote => true, html: {id: :activity_create_form, "data-type" => :json} do |f| %>
    <%= f.input :name, label: "Activity name", input_html: { id: "create_activity_name_field" }, hint: "At least 7 characters" %>
    <%= f.input :type, label: "Activity type", input_html: { id: "create_activity_type_field" }, as: :select, :include_blank => false, collection: Activity.types.keys.to_a %>
    <%= f.input :date_field, input_html: { id: "create_activity_date_field" }, as: :string %>
    <%= f.input :time_field, input_html: { id: "create_activity_time_field" }, as: :string %>
    <%= f.button :submit, :class => "btn btn-primary", input_html: {id: "create_activity_submit_btn"} -%>
<% end %>
#activity_new.js
$("form").submit( function (e) {
        e.preventDefault();

        $('<input />')
                    .attr('type', 'hidden')
                    .attr('name', 'routeGeoJson')
                    .attr('value', JSON.stringify(polyline.toGeoJSON()))
                    .appendTo(this);
        return true;
});
def create
   geojson = JSON.parse(params[:routeGeoJson])
   # do something...
end