新手问题 Ajax 里用 append 嵌入一段 Rails 代码

miserytan · 发布于 2017年07月13日 · 最后由 zaqmjuop 回复于 2017年07月15日 · 536 次阅读
5c8fb2

我有如下代码,想通过onchange事件获取到下拉列表里的值,然后通过ajax传递到前端页面中,并想用append嵌入一段功能为下拉菜单的rails代码到我预留出来的域里.

<div class="object-select col-lg-6" style="float:left" >          
    <%= f.select :software_kingdom, options_for_select(ProductCatalog.where('parent_id =?',1).map{|t|[t.name,t.id]},@app.software_kingdom),
                                                            :include_blank => true, :label => l(:label_product_catalog_software_kingdom) %>
</div>
<div id ="system_domain" class="object-select col-lg-6" >

</div>
$(document).ready(
        function () {
              $("#app_software_kingdom").on("change", function () {
                  var soft_king =$("#app_software_kingdom option:selected");
                  var soft_select = soft_king.val();
          $.ajax({
                          url: "new",
                          data: {soft_selectid: soft_select},
                          success: function(data){
                         $('#app_software_kingdom').val(data.soft_king);
$('#system_domain').append(<%=f.select:system_domain,options_for_select(ProductCatalog.where('parent_id=?',data.soft_king).map{|t[t.name,t.id]},@user2omain),:include_blank => true, :label => l(:label_product_catalog_system_domain) %>");
# 这里忽略(,@user2omain)这个是我没有的,可能是编译的时候出现了问题
                          }
                  });

            });
})
class AppsController < ApplicationController
    def new
        @app = @project.apps.new
        if !params[:soft_selectid].blank?
            @product_ware = ProductCatalog.where(:id => params[:soft_selectid])

            respond_to do |format|

                format.json { render :json => { :software_kingdom => @product_ware.first.id}}
            end
      end
  end
end

但是现在总报这个错误

共收到 15 条回复
11562
$('#app_software_kingdom').val(data.soft_king);
$('#system_domain').append(<%=f.select:system_domain,options_for_select(ProductCatalog.where('parent_id=?',data.soft_king).map{|t[t.name,t.id]},@user2omain),:include_blank => true, :label => l(:label_product_catalog_system_domain) %>");

报错的提示很明白 是没有data方法,那么就是这一句有问题

ProductCatalog.where('parent_id=?',data.soft_king)

检查下吧。

5c8fb2
11562hging 回复

是的就是这个data.soft_king 有问题,可是怎么将js的变量塞入到rails的代码中呢

5c8fb2
11562hging 回复

或者是有什么办法可以解决这个尴尬的情况,因为不单单是data.soft_king这个有问题,我将data.soft_king 换成一个常量比如2,也是不好用的,所以我断定可能是这里的append不可以写rails的代码,可能不识别,所以有什么办法可以解决吗

27861

append里面可以写rails代码。<%= f.select xxx %>里面的f是一个普通变量,不是实例变量无法进行转换。把f.select xxx在后台拼接而成再传给前端你试试。

5c8fb2
11562hging 回复

我用的这种方法来解析rails代码,但是data.soft_king 还是报错,我应该怎么解析这个js变量呢

$('#system_domain').append("<%= escape_javascript(f.select :system_domain, options_for_select(ProductCatalog.where('parent_id =?',data.soft_king).map{|t|[t.name,t.id]},@app.system_domain),:include_blank => true, :label => l(:label_product_catalog_system_domain)) %>");
5c8fb2

有没有大神出来帮忙解下围

B44b1b

首先不应该在js里写erb,controller render js时可以,你的data.soft_king是client端代码,你却在server端使用,肯定会有问题,f.select这个也不能这么写,你可以在后台把options取完以json传给前台,或者render js的方法也行。

27861

rails渲染view的时候会根据erb模板默认规则把代码进行转换,helper方法和@实例变量会转换成静态值在页面显示,<%= f.select xxx %>会自动变成类似<select><option>的静态 html代码,调用ajax方法的时候 f这鬼东西根本就不存在了,这是服务器端的东西,用户看到的是客户端的静态页面,所以你可以用<select></select>标签来替代<%= f.select %>。 如果是我,我会选择在view里面新建一个_select.html.erb,然后把你那段代码放进来,不要<f.select>,直接用select_tag,配合rails的options_for_select,controller里面render file: '_select.html.erb', 页面直接success(data){ append(data)}

A5aa80

还没学到f.select 所以你的代码不能完全看懂 但是从前端取值在传到后端再ajax可以像这样 取完值后用jq发post请求

var $van = $("#dcpt").text();
$.post("<%= articles_path%>",
    { 
      utf8: "✓",
      authenticity_token: "<%=form_authenticity_token%>",
      van: $van
    }
);

然后 接收

def create
    @van=params[:van] if params[:van]
    respond_to do |format|
        format.js
    end
end

就可以引用了

$("#fuck").append("<%=@van%>");
Ce5931
A5aa80zaqmjuop 回复

前后端分离的写法

5c8fb2
B44b1bfan124 回复

你说的对

5c8fb2

我有写过这种前后端分离的,当时append一个变量到我的前端页面中,这个变量是我用来获取我的option的

success: function(data){
             $('#app_software_kingdom').val(data.soft_king);
                $('#system_domain').append("<% @system_dom %>");
             }

然后前台页面里,我直接用这个变量

<%= f.select :system_domain, options_for_select(ProductCatalog.where('parent_id =?', @system_dom.to_i ).map{|t|[t.name,t.id]},@app_project.system_domain),:include_blank => true, :label => l(:label_product_catalog_system_domain)  %>

options_for_select里面的option我都能获取到了,

但是界面上的下拉框还是空的,这是怎么回事

@Rei

A5aa80

append("<% ======@= %>") render plain: params.inspect

5c8fb2
A5aa80zaqmjuop 回复

什么意思?有些新手,还望耐心指教下

5c8fb2 miserytan 关闭了讨论 07月14日 14:48
5c8fb2 miserytan 重新开启了讨论 07月14日 17:15
A5aa80
Ce5931seven.lee 回复

不懂什么是前后端分离,我以为可以把ruby变量插在js中是因为有erb吧

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册